android hal log,Android使用HAL操作LED

1.在hardware/libhardware/include/hardware/目录下新建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

2.在hardware/libhardware/modules/目录下新建led目录,再在led目录下新建led_hal.c文件和Android.mk文件,led_hal.c内容如下:

#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/msmgpio", 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, which, status);

ALOGI("led_ctrl : %d, %d, %d", which, status, ret);

return ret;

}

static struct led_device_t led_dev = {

.common = {

.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 = {

.id = "led",

.methods = &led_module_methods,

};在led_open中,会打开/dev/msmgpio节点,led_open被JNI调用,后面会分析。

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 := userdebug

修改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));

}

}ledOpen调用hw_get_module("led", (hw_module_t const**)&module);hw_get_module函数中在hardware/libhardware/hardware.c文件中实现:

int hw_get_module(const char *id, const struct hw_module_t **module)

{

return hw_get_module_by_class(id, NULL, module);

}hw_get_module调用hw_get_module_by_class,改函数实现如下:

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);

/*

* 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

if (property_get(variant_keys[i], prop, NULL) == 0) {

continue;

}

if (hw_module_exists(path, sizeof(path), name, prop) == 0) {

goto found;

}

}

/* Nothing found, try the default */

if (hw_module_exists(path, sizeof(path), name, "default") == 0) {

goto found;

}

return -ENOENT;

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);

}传入的inst参数为空,所以走else分支,name = "led", $ mmm frameworks/base/services $ mmm hardware/libhardware/modules/led $ make snod $ ./gen-img.sh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值