Ubuntu 에 서 는 Android HAL 의 JNI 작성 방법 에 JAVA 액세스 하드웨어 서비스 인 터 페 이 스 를 제공 합 니 다.

지난 두 편의 글 에서 우 리 는 안 드 로 이 드 시스템 의 하드웨어 를 위해 드라이버 를 만 드 는 방법 을 소개 했다.리 눅 스 커 널 공간 에서 커 널 드라이버 를 실현 하 는 방법 과 사용자 공간 에서 하드웨어 추상 층 인 터 페 이 스 를 실현 하 는 방법 을 포함한다.이 두 가 지 를 실현 하 는 목적 은 하드웨어 액세스 인터페이스,즉 안 드 로 이 드 의 Application Frameworks 층 에 하드웨어 서 비 스 를 제공 하 는 것 이다.안 드 로 이 드 시스템 의 응용 프로그램 은 자바 언어 로 작 성 된 것 이 고 하드웨어 드라이버 는 C 언어 로 이 루어 진 것 을 알 고 있 습 니 다.그렇다면 자바 인 터 페 이 스 는 어떻게 C 인 터 페 이 스 를 방문 합 니까?자바 가 JNI 방법 호출 을 제공 한 것 은 잘 알려 져 있 습 니 다.마찬가지 로 안 드 로 이 드 시스템 에서 자바 응용 프로그램 은 JNI 를 통 해 하드웨어 추상 층 인 터 페 이 스 를 호출 합 니 다.이 글 에서 우 리 는 안 드 로 이 드 하드웨어 추상 층 인터페이스 에 JNI 를 만 드 는 방법 을 소개 하여 상부 의 자바 응용 프로그램 이 하부 에서 제공 하 는 하드웨어 서 비 스 를 사용 할 수 있 도록 할 것 이다.
      1.Ubuntu Android 하드웨어 추상 층(HAL)모듈 추가 Linux 커 널 드라이버 방문글 을 참조 하여 하드웨어 추상 층 모듈 을 준비 하여 Android 시스템 미 러 파일 system.img 에 hello.default 모듈 이 포함 되 어 있 는 지 확인 합 니 다.
      2.frameworks/base/services/jni 디 렉 터 리 에 들 어가 서 새로운 comandroid_server_HelloService.cpp 파일:
      USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/services/jni
      USER-NAME@MACHINE-NAME:~/Android/frameworks/base/services/jni$ vi com_android_server_HelloService.cpp
      comandroid_server_Hello Service.cpp 파일 에서 JNI 방법 을 구현 합 니 다.파일 의 명령 방법 에 주의 하 세 요,comandroid_server 접 두 사 는 패키지 이름 을 표시 합 니 다.하드웨어 서비스 HelloService 는 frameworks/base/services/자바 디 렉 터 리 에 있 는 come/android/server 디 렉 터 리 를 표시 합 니 다.즉,come.android.server.HelloService 라 는 명령 이 존재 합 니 다.여기 서 저 희 는 HelloService 류 의 묘 사 를 잠시 생략 하고 다음 글 에서 HelloService 류 로 돌아 가 겠 습 니 다.쉽게 말 하면 HelloService 는 자바 인 터 페 이 스 를 제공 하 는 하드웨어 액세스 서비스 클래스 입 니 다.
      우선 해당 헤더 파일 을 포함 합 니 다:

#define LOG_TAG "HelloService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/hello.h>
#include <stdio.h>
 이어서 helloinit、hello_getVal 과 hellosetVal 세 가지 JNI 방법:

namespace android
{
	/*                 ,  <hardware/hello.h>*/
 struct hello_device_t* hello_device = NULL;
	/*                       val  */
 static void hello_setVal(JNIEnv* env, jobject clazz, jint value) {
		int val = value;
		LOGI("Hello JNI: set value %d to device.", val);
		if(!hello_device) {
			LOGI("Hello JNI: device is not open.");
			return;
		}
		
		hello_device->set_val(hello_device, val);
	}
 /*                       val  */
	static jint hello_getVal(JNIEnv* env, jobject clazz) {
		int val = 0;
		if(!hello_device) {
			LOGI("Hello JNI: device is not open.");
			return val;
		}
		hello_device->get_val(hello_device, &val);
		
		LOGI("Hello JNI: get value %d from device.", val);
	
		return val;
	}
 /*                        */
	static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) {
		return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
	}
 /*      ID                  */
	static jboolean hello_init(JNIEnv* env, jclass clazz) {
		hello_module_t* module;
		
		LOGI("Hello JNI: initializing......");
		if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
			LOGI("Hello JNI: hello Stub found.");
			if(hello_device_open(&(module->common), &hello_device) == 0) {
				LOGI("Hello JNI: hello device is open.");
				return 0;
			}
			LOGE("Hello JNI: failed to open hello device.");
			return -1;
		}
		LOGE("Hello JNI: failed to get hello stub module.");
		return -1;		
	}
 /*JNI   */
	static const JNINativeMethod method_table[] = {
		{"init_native", "()Z", (void*)hello_init},
		{"setVal_native", "(I)V", (void*)hello_setVal},
		{"getVal_native", "()I", (void*)hello_getVal},
	};
 /*  JNI  */
	int register_android_server_HelloService(JNIEnv *env) {
 		return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table));
	}
};
 주의,helloinit 함수 에서 Android 하드웨어 추상 층 을 통 해 제공 하 는 hwget_module 방법 으로 모듈 ID 를 HELLO 로 불 러 옵 니 다.HARDWARE_MODULE_ID 의 하드웨어 추상 층 모듈,그 중 HELLOHARDWARE_MODULE_ID 는에서 정 의 됩 니 다.Android 하드웨어 추상 층 은 HELLOHARDWARE_MODULE_ID 의 값 은 Android 시스템 의/system/lib/hw 디 렉 터 리 에서 해당 모듈 을 찾 은 다음 불 러 오고 hw 로 돌아 갑 니 다.module_t 인 터 페 이 스 는 호출 자 에 게 사용 된다.jni RegisterNativeMethods 함수 에서 두 번 째 매개 변수의 값 은 HelloService 가 있 는 가방 의 경로,즉 com.android.server.HelloService 에 대응 해 야 합 니 다.
      3.같은 디 렉 터 리 에 있 는 onload.cpp 파일 을 수정 합 니 다.먼저 namespace android 에 register 를 추가 합 니 다.android_server_HelloService 함수 설명:
namespace android {
      ..............................................................................................
      int register_android_server_HelloService(JNIEnv *env);
      };
 JNI 에서onLoad 증가 registerandroid_server_HelloService 함수 호출:
extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved)
      {
       .................................................................................................
       register_android_server_HelloService(env);
       .................................................................................................
      }
 이렇게 하면 Android 시스템 이 초기 화 될 때 이 JNI 방법 호출 표를 자동 으로 불 러 옵 니 다.
         4.같은 디 렉 터 리 에 있 는 Android.mk 파일 을 수정 하고 LOCALSRC_FILES 변수 에 한 줄 추가:
      LOCAL_SRC_FILES:= \
      com_android_server_AlarmManagerService.cpp \
      com_android_server_BatteryService.cpp \
      com_android_server_InputManager.cpp \
      com_android_server_LightsService.cpp \
      com_android_server_PowerManagerService.cpp \
      com_android_server_SystemServer.cpp \
      com_android_server_UsbService.cpp \
      com_android_server_VibratorService.cpp \
      com_android_server_location_GpsLocationProvider.cpp \
      com_android_server_HelloService.cpp /
      onload.cpp
 5.억 system.img 을 컴 파일 하고 다시 찾 습 니 다.
      USER-NAME@MACHINE-NAME:~/Android$ mmm frameworks/base/services/jni
      USER-NAME@MACHINE-NAME:~/Android$ make snod
      이렇게 해서 다시 포장 한 system.img 미 러 파일 은 우리 가 방금 작성 한 JNI 방법 을 포함 합 니 다.즉,우 리 는 안 드 로 이 드 시스템 의 Application Frameworks 층 이 제공 하 는 하드웨어 서비스 HelloService 를 통 해 이러한 JNI 방법 을 호출 하고 낮은 층 의 하드웨어 추상 층 인 터 페 이 스 를 호출 하여 하드웨어 에 접근 할 수 있 습 니 다.앞에서 언급 한 바 와 같이 이 글 에서 저 희 는 HelloService 류 의 실현 을 잠시 소홀히 했 습 니 다.다음 글 에서 저 희 는 하드웨어 서비스 HelloService 를 어떻게 실현 하 는 지 설명 할 것 입 니 다.주목 해 주 십시오.
이상 은 JNI 방법 으로 안 드 로 이 드 하드웨어 추상 층 을 방문 하 는 절 차 를 작성 하고 관련 지식 을 계속 보충 하 며 안 드 로 이 드 소스 코드 를 연구 하 는 학생 들 에 게 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기