【版权申明】转载请附上出处链接
Android的硬件访问服务添加
Android设备端
- 在frameworks\base\core\java\android\os文件夹下新建自己的aidl
AIDL(Android Interface Definition Language), 即Android接口定义语言.
package android.os;
/** {@hide} 表示这个接口是系统隐藏接口 */
interface ILedService
{
int ledCtrl(int which, int status);
}
- 修改frameworks\base目录下的Android.mk文件, 添加我们上面的aidl到系统的SDK API中.
LOCAL_SRC_FILES += \
......
core/java/android/os/ILedService.aidl \
......
- 执行mmm命令, 等待ILedService.java文件的生成.
# mmm: 对Android源码中的指定模块进行编译
frameworks $mmm
或
$mmm frameworks
$ls -l out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ILedService.java
-rw-rw-r-- 1 yangbkGit yangbkGit 2539 4月 27 21:55 ILedService.java
- 在frameworks\base\services\core\java\com\android\server目录下, 新建LedService.java文件.
package com.android.server;
import android.os.ILedService;
public class LedService extends ILedService.Stub
{
private static final String TAG = "LedService";
public LedService() {
native_ledOpen();
}
public int ledCtrl(int which, int status) throws android.os.RemoteException
{
return native_ledCtrl(which, status);
}
/* call native C function to access hardware */
public static native int native_ledOpen();
public static native int native_ledCtrl(int which, int status);
public static native int native_ledClose();
}
- 修改frameworks\base\services\java\com\android\server\SystemServer.java文件, 在startOtherServices()函数中添加我们新建的服务.
LedService led = null;
Slog.i(TAG, "Led Service");
led = new LedService();
ServiceManager.addService("led", led);
- 在frameworks\base\services\core\jni目录下, 新建com_android_server_LedService.cpp文件, 注册本地方法, 供LedService.java使用.
#define LOG_TAG "LedService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/led_hal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define USE_LED_HAL
namespace android
{
#ifdef USE_LED_HAL
static struct led_device_t *led_device;
#else
static jint fd;
#endif
jint ledOpen(JNIEnv *env, jobject cls)
{
#ifdef USE_LED_HAL
jint err;
hw_module_t* module;
hw_device_t* device;
ALOGI("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 = (struct led_device_t *)device;
return led_device->led_open(led_device);
} else {
return -1;
}
}
return -1;
#else
fd = open("/dev/yangbkDevice", O_RDWR);
ALOGI("ledOpen() fd = %d", fd);
if(fd < 0){
return -1;
}
return 0;
#endif
}
void ledClose(JNIEnv *env, jobject cls)
{
#ifdef USE_LED_HAL
#else
close(fd);
ALOGI("ledClose");
#endif
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
#ifdef USE_LED_HAL
ALOGI("ledCtrl: %d, %d", which, status);
return led_device->led_ctrl(led_device, which, status);
#else
int ret = ioctl(fd, status, which);
ALOGI("ledCtrl() ret = %d, %d, %d", ret, which, status);
return ret;
#endif
}
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));
}
};
- 修改frameworks\base\services\core\jni\onload.cpp文件, 添加我们服务:
// 声明
int register_android_server_LedService(JNIEnv* env);
// JNI_OnLoad()函数中
register_android_server_LedService(env);
- 修改frameworks\base\services\core\jni目录下的Android.mk文件, 在LOCAL_SRC_FILES变量中添加如下:
$(LOCAL_REL_DIR)/com_android_server_LedService.cpp \
- 在hardware\libhardware\include\hardware目录下新建led_hal.h文件, 添加头文件, 使用hal方式调用led的驱动.
#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
- 在hardware\libhardware\modules目录下新建led文件夹, 在文件夹下新建led_hal.c文件和Android.mk文件:
#define LOG_TAG "led_hal"
#include <hardware/hardware.h>
#include <hardware/led_hal.h>
#include <cutils/log.h>
#include <utils/Log.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
static int fd = -1;
static int led_open(struct hw_device_t* device)
{
fd = open("/dev/yangbkDevice", O_RDWR);
ALOGI("ledOpen() fd = %d", fd);
if(fd < 0){
return -1;
}
return 0;
}
static int led_close(struct hw_device_t* device)
{
close(fd);
return 0;
}
static int led_ctrl(struct led_device_t *dev, int which, int status)
{
int ret = ioctl(fd, status, which);
ALOGI("ledCtrl() ret = %d, %d, %d", ret, which, status);
return ret;
}
static struct led_device_t led_dev = {
.common = {
.close = led_close,
},
.led_open = led_open,
.led_ctrl = led_ctrl,
};
/** Open a specific device */
static int led_device_open(const struct hw_module_t* module, const char* id,
struct hw_device_t** device)
{
*device = &led_dev;
return 0;
}
/*===========================================================================*/
/* Default led HW module interface definition */
/*===========================================================================*/
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,
};
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := led.default
# HAL module implementation stored in
# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so
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)
- 编译(在Android工程的根目录下)
得到根目录下的system.img和out/target/product/tiny4412/目录下的system.img
烧录进板子即可.
$. setenv
$mmm frameworks/base/services
$mmm hardware/libhardware/modules/led
$make snod
$./gen-img.sh
Android应用端
- 将out\target\common\obj\JAVA_LIBRARIES\framework_intermediates目录下的classes.jar导入Android应用工程, 然后点击同步
2. 在需要的地方获得我们添加的服务并使用服务:
import android.os.ILedService;
private ILedService iLedService;
iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
iLedService.ledCtrl(0, (isChecked ? 1 : 0));