Android 드라이버 (1) 하드웨어 액세스 서비스 학습 (3) Android HAL 계층 액세스 하드웨어 가입

  • 하드웨어 플랫폼: tiny 4412
  • 시스템: Android 5.0.2
  • 컴 파일 러: arm-linux-gcc-4.5.1

  • 지난 절 에 우 리 는 하드웨어 액세스 서 비 스 를 실현 하여 하드웨어 를 조작 했다.http://blog.csdn.net/fengyuwuzu0519/article/details/55271199
    당시 에 우 리 는 하드웨어 에 대한 조작 을 JNI 층 에 두 었 지만 안 드 로 이 드 는 그렇지 않 았 다. 구 글 은 HAL 층, 즉 하드웨어 패 키 징 층 을 제시 했다.
    구 글 공식 프레임 워 크:https://developer.android.com/guide/platform/index.html。
    이 절 에서 우 리 는 하드웨어 의 조작 을 HAL 층 으로 밀봉 했다.
    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第1张图片
    안 드 로 이 드 HAL 이 뭐 예요?왜 그것 이 있 습 니까?인터넷 설 을 살 펴 보 자.
    하드웨어 추상 층 은 안 드 로 이 드 커 널 과 상층 부 사이 에 있 는 추상 적 인 구조 이다.그 는 Liux 구동 에 대한 패 키 징 으로 상부 에 통 일 된 인 터 페 이 스 를 제공 합 니 다. 상부 응용 은 하층 하드웨어 가 구체 적 으로 어떻게 업 무 를 실현 하 는 지 알 필요 가 없습니다. 이것 은 하층 의 실현 디 테 일 을 차단 합 니 다.
    전체 안 드 로 이 드 구조 에 있 는 위 치 는 다음 그림 과 같 습 니 다.
    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第2张图片
    전통 적 인 Liux 가 하드웨어 에 대한 조작 은 기본적으로 커 널 공간의 Liux 드라이버 에서 이 루어 졌 습 니 다. 그러면 지금 은 왜 이렇게 많은 일 들 이 하드웨어 에 대한 조작 을 두 부분, hal 과 Liux 로 나 누 었 습 니까?
    그리고 hal 은 사용자 공간 에 속 하고 Liux 구동 은 커 널 공간 에 속한다.사실 불필요 하지 않다.그렇다면 왜 이런 물건 보다 높 아야 하 는 지 이 유 는 매우 많다.
    1. 구 글 은 hal 의 프레임 워 크 를 구축 하여 상층 framework 에 jni 호출 hal 을 통 해 통 일 된 api 를 제공 했다. 하드웨어 개발 업 체 나 이식 자 는 프레임 워 크 에 따라 개발 하면 된다. 전화 비용 없 이 상층 과 의 상호작용 을 실현 하고 hal 층 자체 의 실제 상황 에 정력 을 기울 이면 된다.
    2. 상업 적 인 측면 에서 많은 하드웨어 업 체 들 이 자신의 하드웨어 와 관련 된 핵심 적 인 것들 을 소스 에서 꺼 내 는 것 을 원 하지 않 는 다. 만약 에 자신의 하드웨어 에 대한 드라이버 를 모두 커 널 공간 드라이버 에 넣 어서 실현 하려 면 반드시 GPL 협 의 를 따라 야 한다. 반드시 소스 를 켜 야 한다.HAL 층 이 생기 면 그들 은 핵심 적 인 알고리즘 과 같은 것들 의 실현 을 HAL 층 에 놓 을 수 있 고 hal 층 은 사용자 공간 에 위치 하 며 Liux 커 널 에 속 하지 않 으 며 안 드 로 이 드 소스 코드 와 마찬가지 로 appache 프로 토 콜 을 따 를 수 있 습 니 다. 이것 은 소스 를 시작 하거나 열지 않 을 수 있 습 니 다.
    다음은 하드웨어 추상 층 인 HAL 을 배 워 보 겠 습 니 다.
    HAL 의 사고방식
    1. 전체적인 사고방식
    (1) 응용 프로그램 은 하드웨어 에 직접 접근 하지 않 습 니 다. 하드웨어 접근 은 SystemServer 에서, SystemServer 에 서 는 JNI 에서 HAL 층 에 접근 합 니 다.
    (2) JNI 는 로 컬 함 수 를 위로 제공 하고 HAL 파일 을 아래로 불 러 오고 HAL 함 수 를 호출 합 니 다.
    (3) HAL 은 드라이버 를 방문 하여 하드웨어 작업 을 수행 하 는 것 을 책임 집 니 다. (더욱 비밀 을 지 키 고 안전 하 며 편리 하 며 GPL 프로 토 콜 을 피 합 니 다)
    (4) JNI 가 HAL 을 불 러 오 는 실질 은 dlopen 을 사용 하여 동적 라 이브 러 리 를 불 러 오 는 것 입 니 다.
    (5) 안 드 로 이 드 는 dlopen 을 패키지 하고 hw 를 사용 합 니 다.get_module。
    2. 상세 분석
    (1) 검색: hwget_module 아래 열기
    조명 시스템 의 JNI 파일: comandroid_server_lights_LightsService.cpp(frameworks\base\services\core\jni)

    (2) hw 찾기get_module

    (3) 더 블 클릭 으로 hwget_module, 최종 호출 hwget_module_by_class("led",NULL)
    int hw_get_module(const char *id, const struct hw_module_t **module)
    {
        return hw_get_module_by_class(id, NULL, module);
    }
    

    클릭 hwget_module_by_class
    hw_get_module_by_class("led",NULL)
    --》strlcpy(name, class_id, PATH_MAX);그래서 name = "led"
    int hw_get_module_by_class(const char *class_id, const char *inst,
                               const struct hw_module_t **module)
    {
        int i;
        char prop[PATH_MAX];
        char path[PATH_MAX];
        char name[PATH_MAX];
        char prop_name[PATH_MAX];
    
        if (inst)
            snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
        else
            strlcpy(name, class_id, PATH_MAX);                                                   //name=led
    
        /*
         * Here we rely on the fact that calling dlopen multiple times on
         * the same .so will simply increment a refcount (and not load
         * a new copy of the library).
         * We also assume that dlopen() is thread-safe.
         */
    
        /* First try a property specific to the class and possibly instance */
        snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
        if (property_get(prop_name, prop, NULL) > 0) {
            if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
                goto found;
            }
        }
    
        /* Loop through the configuration variants looking for a module */
        for (i=0 ; i

    (4) 주로 두 함수, property 를 사 용 했 습 니 다.get 과 hwmodule_exists
    hw_module_exists: 판단 에 사용 "name". "subname". so 는 세 개의 고정된 디 렉 터 리 에 존재 하 는 지 여부 입 니 다.
    name 은 상층 hwget_module_by_class 가 들 어 오 는 name = led, 즉 led. "subname". so 가 존재 하 는 지 판단 합 니 다.subname 도 상위 함수 에서 제공 하 는 prop, 즉 가 져 온 속성 값 입 니 다.여 기 는 일단 어떤 SO 의 존재 여 부 를 판단 하 는 것 으로 본다.
    a. 환경 변수 획득 경로: char * hallibrary_path =getenv("HAL_LIBRARY_PATH");        
    환경 변수 에서 결 정 된 경로: snprintf (path, path len, "% s /% s.% s. so",
                     hal_library_path, name, subname);
     존재 여 부 를 판단 하 는 if (access (path, R OK) = = 0)            return 0;
    b.#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
    동 리 판단 /"subname". so 존재 여부
    c.#define HAL_LIBRARY_PATH1 "/system/lib/hw"
    동 리 판단 /system / lib / hw / led. "subname". so 존재 여부
    static int hw_module_exists(char *path, size_t path_len, const char *name,
                                const char *subname)
    {
        char *hal_library_path = getenv("HAL_LIBRARY_PATH");
        if (hal_library_path) {
            snprintf(path, path_len, "%s/%s.%s.so",
                     hal_library_path, name, subname);
            if (access(path, R_OK) == 0)
                return 0;
        }
    
        snprintf(path, path_len, "%s/%s.%s.so",
                 HAL_LIBRARY_PATH2, name, subname);
        if (access(path, R_OK) == 0)
            return 0;
    
        snprintf(path, path_len, "%s/%s.%s.so",
                 HAL_LIBRARY_PATH1, name, subname);
        if (access(path, R_OK) == 0)
            return 0;
    
        return -ENOENT;
    }
    

    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第3张图片 Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第4张图片
    분명히 4412 는 / system / lib / hw 에서 "name", "subname", so 파일 이 존재 하 는 지 찾 습 니 다.
    property_get: android 의 속성 시스템 입 니 다.속성 은 키 쌍 입 니 다. 이름 에 따라 값 을 가 져 옵 니 다.
    property_get(prop_name, prop, NULL):prop_name: 키     prop: 가 져 온 값
    hw_get_module_by_class 중 propertyget 이 여러 번 호출 되 었 습 니 다.
    제1차 propname="ro.hardware.%s", name
    이후: propname=
    static const char *variant_keys[] = {
        "ro.hardware",  /* This goes first so that it can pick up a different
                           file on the emulator. */
        "ro.product.board",
        "ro.board.platform",
        "ro.arch"
    };


    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第5张图片

    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第6张图片

    소프트 속성 이 존재 합 니 다. led. prop. so 가 세 디 렉 터 리 에 존재 하 는 지 판단 합 니 다.
    존재 하지 않 으 면 led. default. so 가 존재 하 는 지 판단 합 니 다.
    마지막 Android. mk 를 통 해 파일 을 컴 파일 합 니 다. 저희 파일 은 led. default. so 로 컴 파일 되 고 놓 여 있 음 을 알 고 있 습 니 다. /시스템 / lib / hw 디 렉 터 리 아래.
    (5)hw_get_module_by_class 는 최종 적 으로 load 로 딩 C 라 이브 러 리 를 호출 합 니 다.
    found:
        /* load the module, if this fails, we're doomed, and we should not try
         * to load a different variant. */
        return load(class_id, path, module);

    (6) dlopen + dlsym 가 져 오기 hwmodule_t 구조 체.
    handle = dlopen(path, RTLD_NOW);//C 라 이브 러 리 불 러 오기
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym);// 불 러 온 후 dlsym 으로 HMI 기 호 를 가 져 옵 니 다. 이 기 호 는 hw 로 변환 합 니 다.module_t 구조 체.So 파일 에서 HMI 라 는 구조 체 를 가 져 와 구조 체 이름과 'led' 가 일치 하 는 지 판단 하고 일치 하면 이 모듈 을 찾 아 마지막 으로 모듈 을 부여 합 니 다.    *pHmi = hmi;변수 pHMi 는 호출 자가 들 어 왔 습 니 다.
    static int load(const char *id,
            const char *path,
            const struct hw_module_t **pHmi)
    {
        int status;
        void *handle;
        struct hw_module_t *hmi;
    
        /*
         * load the symbols resolving undefined symbols before
         * dlopen returns. Since RTLD_GLOBAL is not or'd in with
         * RTLD_NOW the external symbols will not be global
         */
        handle = dlopen(path, RTLD_NOW);
        if (handle == NULL) {
            char const *err_str = dlerror();
            ALOGE("load: module=%s
    %s", path, err_str?err_str:"unknown"); status = -EINVAL; goto done; } /* Get the address of the struct hal_module_info. */ const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym); if (hmi == NULL) { ALOGE("load: couldn't find symbol %s", sym); status = -EINVAL; goto done; } /* Check that the id matches */ if (strcmp(id, hmi->id) != 0) { ALOGE("load: id=%s != hmi->id=%s", id, hmi->id); status = -EINVAL; goto done; } hmi->dso = handle; /* success */ status = 0; done: if (status != 0) { hmi = NULL; if (handle != NULL) { dlclose(handle); handle = NULL; } } else { ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p", id, path, *pHmi, handle); } *pHmi = hmi; return status; }
    (7)
    JNI
    HAL 을 어떻게 사용 하 는 지.
    a.    JNI 호출 hwget_module 모듈 이름 "led" 를 통 해 so 파일 을 열 어 hwmodule_t 구조 체
    b. 이후 getdevice(module,LIGHT_ID_BACKLIGHT);장치 이름 을 입력 합 니 다. hwget_module 에서 이 장치 가 져 오기 hwdevice_t
    module - > methods - > open (module, device name, & device) 을 호출 하여 hw 획득device_t 구조 체, 그리고 hwdevice_t 구조 체 를 장치 사용자 정의 구조 체 light 로 변환device_t。
    light_device_t 첫 번 째 멤버 는 hwdevice_t, 유형 변환 이 가능 합 니 다.
    static light_device_t* get_device(hw_module_t* module, char const* name)
    {
        int err;
        hw_device_t* device;
        err = module->methods->open(module, name, &device);
        if (err == 0) {
            return (light_device_t*)device;
        } else {
            return NULL;
        }
    }

    (8) HAL 은 어떻게 써 요
    a. HMI 라 는 hw 구현module_t 구조 체
    b. open 함 수 를 실현 하면 devicename 장치 사용자 정의 구조 체 되 돌려 주기
    c. 장치 구조 체 를 실현 합 니 다. 이 장치 가 사용자 정의 하 는 구조 체 의 첫 번 째 구성원 은 hw 입 니 다.device_t 구조 체 는 장치 와 관련 된 구성원 도 정의 할 수 있다.예:
    struct led_device_t {
        struct hw_device_t common;
    	int (*led_open)(struct led_device_t* dev);
    	int (*led_ctrl)(struct led_device_t* dev, int which, int status);
    };
    
    (9) 반나절 동안 모듈 의 구조 체 를 말 했 는데 HAL 층 의 중요 한 구조 체 몇 개 를 살 펴 보 겠 습 니 다.
    hw_module_t 구조 체, hwmodule_methods_t 구조 체, hwdevice_t 구조 체
    hw_module_t:
    하드웨어 모듈 을 나타 내 는데 주로 하드웨어 모듈 의 정보, 구조 체 의 정 의 를 포함한다.
    안쪽 hwmodule_methods_t, 이 포인터 methods 는 본 하드웨어 모듈 과 관련 된 방법의 구조 체 를 가리 키 고 있 습 니 다.
    typedef struct hw_module_t {
        /** tag must be initialized to HARDWARE_MODULE_TAG */
        uint32_t tag;
    
        /**
         * The API version of the implemented module. The module owner is
         * responsible for updating the version when a module interface has
         * changed.
         *
         * The derived modules such as gralloc and audio own and manage this field.
         * The module user must interpret the version field to decide whether or
         * not to inter-operate with the supplied module implementation.
         * For example, SurfaceFlinger is responsible for making sure that
         * it knows how to manage different versions of the gralloc-module API,
         * and AudioFlinger must know how to do the same for audio-module API.
         *
         * The module API version should include a major and a minor component.
         * For example, version 1.0 could be represented as 0x0100. This format
         * implies that versions 0x0100-0x01ff are all API-compatible.
         *
         * In the future, libhardware will expose a hw_get_module_version()
         * (or equivalent) function that will take minimum/maximum supported
         * versions as arguments and would be able to reject modules with
         * versions outside of the supplied range.
         */
        uint16_t module_api_version;
    #define version_major module_api_version
        /**
         * version_major/version_minor defines are supplied here for temporary
         * source code compatibility. They will be removed in the next version.
         * ALL clients must convert to the new version format.
         */
    
        /**
         * The API version of the HAL module interface. This is meant to
         * version the hw_module_t, hw_module_methods_t, and hw_device_t
         * structures and definitions.
         *
         * The HAL interface owns this field. Module users/implementations
         * must NOT rely on this value for version information.
         *
         * Presently, 0 is the only valid value.
         */
        uint16_t hal_api_version;
    #define version_minor hal_api_version
    
        /** Identifier of module */
        const char *id;
    
        /** Name of this module */
        const char *name;
    
        /** Author/owner/implementor of the module */
        const char *author;
    
        /** Modules methods */
        struct hw_module_methods_t* methods;
    
        /** module's dso */
        void* dso;
    
    #ifdef __LP64__
        uint64_t reserved[32-7];
    #else
        /** padding to 128 bytes, reserved for future use */
        uint32_t reserved[32-7];
    #endif
    
    } hw_module_t;

    hw_module_methods_t:
    함수 포인터 open 하드웨어 모듈 의 하드웨어 장 치 를 여 는 함수 입 니 다.
    typedef struct hw_module_methods_t {
        /** Open a specific device */
        int (*open)(const struct hw_module_t* module, const char* id,
                struct hw_device_t** device);
    
    } hw_module_methods_t;

    hw_device_t:
    모듈 에 있 는 하드웨어 장치 의 속성 정 보 를 설명 합 니 다.하드웨어 모듈 에 여러 개의 하드웨어 장치 가 있 을 수 있 습 니 다.
    예 를 들 어 센서 모듈, sensormodule, 하드웨어 모듈 이지 만 핸드폰 에 있 는 센서 는 여러 가지 가 있 습 니 다. 예 를 들 어 가속도 acc센서, 자기 센서 Msensor 등, 그러면 그들 은 모두 sensor 에 속한다.module, 하지만 그들 은 모두 자신의 hw 가 있다.device_t 구조 체 로 설명 합 니 다.
    module 은 이 장치 에 속 하 는 하드웨어 모듈 구조 체 를 가리킨다.함수 포인터 close 는 장 치 를 닫 는 함 수 를 가리킨다.
    typedef struct hw_device_t {
        /** tag must be initialized to HARDWARE_DEVICE_TAG */
        uint32_t tag;
    
        /**
         * Version of the module-specific device API. This value is used by
         * the derived-module user to manage different device implementations.
         *
         * The module user is responsible for checking the module_api_version
         * and device version fields to ensure that the user is capable of
         * communicating with the specific module implementation.
         *
         * One module can support multiple devices with different versions. This
         * can be useful when a device interface changes in an incompatible way
         * but it is still necessary to support older implementations at the same
         * time. One such example is the Camera 2.0 API.
         *
         * This field is interpreted by the module user and is ignored by the
         * HAL interface itself.
         */
        uint32_t version;
    
        /** reference to the module this device belongs to */
        struct hw_module_t* module;
    
        /** padding reserved for future use */
    #ifdef __LP64__
        uint64_t reserved[12];
    #else
        uint32_t reserved[12];
    #endif
    
        /** Close this device */
        int (*close)(struct hw_device_t* device);
    
    } hw_device_t;

    2. 코드 구현:
    (1) JNI 파일 구현 (frameworks / base / services / core / jni / com android server LedService. cpp)
    #define LOG_TAG "LedService"
    
    #include "jni.h"
    #include "JNIHelp.h"
    #include "android_runtime/AndroidRuntime.h"
    
    #include 
    #include 
    
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    namespace android
    {
    
    static led_device_t* led_device;
    
    jint ledOpen(JNIEnv *env, jobject cls)
    {
    	jint err;
        hw_module_t* module;
    	hw_device_t* device;
    
    	ALOGI("native ledOpen ...");
    
    	/* 1. hw_get_module */
        err = hw_get_module("led", (hw_module_t const**)&module);
        if (err == 0) {
    		/* 2. get device : module->methods->open */
    	    err = module->methods->open(module, NULL, &device);
    	    if (err == 0) {
    			/* 3. call led_open */
    	        led_device = (led_device_t *)device;
    			return led_device->led_open(led_device);
    	    } else {
    	        return -1;
        	}
        }
    	
        return -1;	
    }
    
    void ledClose(JNIEnv *env, jobject cls)
    {
    	//ALOGI("native ledClose ...");
    	//close(fd);
    }
    
    
    jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
    {
    	ALOGI("native ledCtrl %d, %d", which, status);
    	return led_device->led_ctrl(led_device, which, status);
    }
    
    
    static const JNINativeMethod methods[] = {
    	{"native_ledOpen", "()I", (void *)ledOpen},
    	{"native_ledClose", "()V", (void *)ledClose},
    	{"native_ledCtrl", "(II)I", (void *)ledCtrl},
    };
    	
    
    int register_android_server_LedService(JNIEnv *env)
    {
        return jniRegisterNativeMethods(env, "com/android/server/LedService",
                methods, NELEM(methods));
    }
    
    }
    
    (2) HAL 코드 구현
    hardware/libhardware/include/hardware/led_hal.h
    hardware/libhardware/modules/led/led_hal.c
    hardware/libhardware/modules/led/Android.mk
    led_hal.c:
    하드웨어 파일 을 공사 에 넣 고 진동기 참조

    카피 헤더 파일
    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第7张图片
    / * 1. HMI 라 는 hw 구현module_t 구조 체 * /
     
    / * 2. open 함 수 를 실현 하고 led 로 돌아 갑 니 다.device_t 구조 체 * /
     
    / * 3. led 실현device_t 구조 체 * /
     
    / * 하드웨어 \ libhardware \ \ modules \ vibrator \ \ vibrator. c 참조
     */
    Android驱动(一)硬件访问服务学习之(三)Android加入HAL层访问硬件_第8张图片
    static struct hw_module_methods_tled_module_methods = {
       .open = led_device_open,
    };
     
    struct hw_module_t HAL_MODULE_INFO_SYM = {
       .id = "led",
        .methods = &led_module_methods,
    };
    #define LOG_TAG "LedHal"
    
    
    /* 1.       HMI hw_module_t    */
    
    /* 2.     open  ,    led_device_t    */
    
    /* 3.   led_device_t    */
    
    /*    hardware\libhardware\modules\vibrator\vibrator.c
     */
    
    #include 
    #include 
    
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    static int fd;
    
    
    /** Close this device */
    static int led_close(struct hw_device_t* device)
    {
    	close(fd);
    	return 0;
    }
    
    static int led_open(struct led_device_t* dev)
    {
    	fd = open("/dev/leds", O_RDWR);
    	ALOGI("led_open : %d", fd);
    	if (fd >= 0)
    		return 0;
    	else
    		return -1;
    }
    
    static int led_ctrl(struct led_device_t* dev, int which, int status)
    {
    	int ret = ioctl(fd, status, which);
    	ALOGI("led_ctrl : %d, %d, %d", which, status, ret);
    	return ret;
    }
    
    
    
    
    static struct led_device_t led_dev = {
    	.common = {
    		.tag   = HARDWARE_DEVICE_TAG,
    		.close = led_close,
    	},
    	.led_open  = led_open,
    	.led_ctrl  = led_ctrl,
    };
    
    static int led_device_open(const struct hw_module_t* module, const char* id,
            struct hw_device_t** device)
    {
    	*device = &led_dev;
    	return 0;
    }
    
    
    static struct hw_module_methods_t led_module_methods = {
        .open = led_device_open,
    };
    
    struct hw_module_t HAL_MODULE_INFO_SYM = {
    	.tag = HARDWARE_MODULE_TAG,
        .id = "led",
        .methods = &led_module_methods,
    };
    
    

    led_hal.h:
    #ifndef ANDROID_LED_INTERFACE_H
    #define ANDROID_LED_INTERFACE_H
    
    #include 
    #include 
    #include 
    
    #include 
    
    __BEGIN_DECLS
    
    struct led_device_t {
        struct hw_device_t common;
    
    	int (*led_open)(struct led_device_t* dev);
    	int (*led_ctrl)(struct led_device_t* dev, int which, int status);
    };
    
    
    __END_DECLS
    
    #endif  // ANDROID_LED_INTERFACE_H
    
    
    
    Android.mk
    # Copyright (C) 2012 The Android Open Source Project
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := led.default
    
    # HAL module implementation stored in
    # hw/.default.so
    LOCAL_MODULE_RELATIVE_PATH := hw            // /system/lib/hw
    LOCAL_C_INCLUDES := hardware/libhardware    //     
    LOCAL_SRC_FILES := led_hal.c                //   C  
    LOCAL_SHARED_LIBRARIES := liblog            //            
    LOCAL_MODULE_TAGS := eng                    //    
    
    include $(BUILD_SHARED_LIBRARY)
    

    3. 컴 파일 업로드
    JNI: 다시 업로드
    frameworks/base/services/core/jni/com_android_server_LedService.cpp
     
    HAL: led_hal.h
            led_hal.c
    서버 에 새 파일 을 업로드 하고 있 는 디 렉 터 리:
    hardware/libhardware/include/hardware/led_hal.h
    hardware/libhardware/modules/led/led_hal.c
    hardware/libhardware/modules/led/Android.mk
    컴 파일:
    $ mmm frameworks/base/services
    $ mmm hardware/libhardware/modules/led
    $ make snod $ ./gen-img.sh
    4. 코드 다운로드:
    이상 코드 다운로드 주소:
    HAL 기반 Android 하드웨어 액세스 서비스 동작 LED tiny 4412 기반
    http://download.csdn.net/detail/fengyuwuzu0519/9883410

    좋은 웹페이지 즐겨찾기