zoukankan      html  css  js  c++  java
  • 第1课第4.4节_Android硬件访问服务编写HAL代码

    android应用如何访问C库 - 落魄影子 - 博客频道 - CSDN.NET  http://blog.csdn.net/ab198604/article/details/51249303

    Android硬件访问服务框架代码编写 - 落魄影子 - 博客频道 - CSDN.NET  http://blog.csdn.net/ab198604/article/details/51397586


    4 编写HAL代码

    源码下载方法
    第一次:
    git clone https://github.com/weidongshan/SYS_0001_LEDDemo.git
    更新:
    git pull origin
    取出指定版本:
    git checkout v1 // 有JNI没有HAL
    git checkout v2 // 有JNI,HAL
    git checkout v3 // add MODULE TAG, DEVICE TAG

    JNI 向上提供本地函数, 向下加载HAL文件并调用HAL的函数
    HAL 负责访问驱动程序执行硬件操作

    dlopen

    externalchromium_org hird_partyhwcplussrchardware.c   (参考代码)
    hw_get_module("led")

    1. 模块名==>文件名
    hw_get_module_by_class("led", NULL)
    name = "led"
    property_get xxx是某个属性
    hw_module_exists 判断是否存在led.xxx.so


    它用来判断"name"."subname".so文件是否存在
    查找的目录:
    a. HAL_LIBRARY_PATH 环境变量

    b. /vendor/lib/hw

    c. /system/lib/hw

     /vendor/lib/hw 这个目录下没有文件,tiny4412所以只能去/system/lib/hw这个目录下找

     

    2. 加载
    load
    dlopen(filename)
    dlsym("HMI") 从SO文件中获得名为HMI的hw_module_t结构体
    strcmp(id, hmi->id) 判断名字是否一致(hmi->id, "led")

    V2:
    (3) JNI: 重新上传
    frameworks/base/services/core/jni/com_android_server_LedService.cpp

    (4) HAL: led_hal.h
    led_hal.c
    把新文件上传到服务器, 所在目录:
    hardware/libhardware/include/hardware/led_hal.h

    hardware/libhardware/modules 在这个目录下创建一个目录led,放入led_hal.c和自己写一个Android.mk

    hardware/libhardware/modules/led/led_hal.c
    hardware/libhardware/modules/led/Android.mk

    Android.mk内容如下:
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := led.default
    LOCAL_MODULE_RELATIVE_PATH := hw
    LOCAL_C_INCLUDES := hardware/libhardware
    LOCAL_SRC_FILES := led_hal.c
    LOCAL_SHARED_LIBRARIES := liblog
    LOCAL_MODULE_TAGS := eng

    include $(BUILD_SHARED_LIBRARY)


    编译:

    $ mmm frameworks/base/services
    $ mmm hardware/libhardware/modules/led
    $ make snod
    $ ./gen-img.sh

     

    最终生成system.img文件


    打印信息简介:
    a. 有三类打印信息: app, system, radio
    程序里使用 ALOGx, SLOGx, RLOGx来打印
    b. x表示6种打印级别,有:
    V    Verbose
    D    Debug
    I     Info
    W   Warn
    E    Error
    F    Fatal

    比如:
    #define LOG_TAG "LedHal"
    ALOGI("led_open : %d", fd);

    c. 打印出来的格式为:
    I/LedHal ( 1987): led_open : 65
    (级别) LOG_TAG 进程号 打印信息

    d. 使用 logcat 命令查看
    logcat LedHal:I *:S

    选出自己感兴趣的信息:

    和上一个章节相比,主要修改了

    com_android_server_LedService.cpp

    添加了led_hal.h   led_hal.c  Android.mk

     com_android_server_LedService.cpp

    #define LOG_TAG "LedService"
    
    #include "jni.h"
    #include "JNIHelp.h"
    #include "android_runtime/AndroidRuntime.h"
    
    #include <utils/misc.h>
    #include <utils/Log.h>
    
    #include <stdio.h>
    
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <hardware/led_hal.h>
    
    
    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));
    }
    
    }

    led_hal.c

    #define LOG_TAG "LedHal"
    
    
    /* 1. 实现一个名为HMI的hw_module_t结构体 */
    
    /* 2. 实现一个open函数, 它返回led_device_t结构体 */
    
    /* 3. 实现led_device_t结构体 */
    
    /* 参考 hardwarelibhardwaremodulesvibratorvibrator.c
     */
    
    #include <hardware/vibrator.h>
    #include <hardware/hardware.h>
    
    #include <cutils/log.h>
    
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    
    #include <hardware/led_hal.h>
    
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <utils/Log.h>
    
    
    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 <stdint.h>
    #include <sys/cdefs.h>
    #include <sys/types.h>
    
    #include <hardware/hardware.h>
    
    __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
  • 相关阅读:
    [MATLAB]Debut-不知名的线性变换
    [Raspberry]使用笔记
    [Algorithm]一切始于ADT-表达式计算
    [python]用request库来处理Http协议-收集北航表白墙内的数据
    [python]os库与shutil库与操作系统的交互-整理硬盘中Vivaldi的作品
    这是一篇使用Live Writer 发布的文章
    [python]re库(正则表达式)的小练习-抓取北航教务处通知列表
    [AVR]使用AVR单片机驱动舵机
    [Python]urllib库的简单应用-实现北航宿舍自动上网
    [Scrapy][转][未完成]关于scrapy命令
  • 原文地址:https://www.cnblogs.com/zhulinhaibao/p/6995461.html
Copyright © 2011-2022 走看看