android源码中添加GPIO服务供上层调用

指定make时需要编译进system中的服务

以rk源码为例,在deveice/rockchip/common/device.mk中添加服务

PRODUCT_PACKAGES += \
    libmoyu-jni \ #服务中用到的jni
    moyu-service
    
 PRODUCT_SYSTEM_SERVER_JARS += \
    moyu-service \ #将服务编译进jar包

添加源码编译

framework/base/Android.mk


LOCAL_SRC_FILES += \
.
.
.
core/java/com/moyu/api/IMoyuManager.aidl \
core/java/com/moyu/api/MoyuManager.java

添加api更新类与字段(此步骤可以通过make update-api命令更新)

framework/base/api/current.txt与framework/base/api/system-current.txt
在Context类中添加字段

field public static final java.lang.String MOYU_SERVICE = "moyu";

添加一个新类

package com.moyu.api {

  public abstract interface IMoyuManager implements android.os.IInterface {
    method public abstract int GetGpioValue(int) throws android.os.RemoteException;
    method public abstract int InitGpio(int, int) throws android.os.RemoteException;
    method public abstract int SetGpioValue(int, int) throws android.os.RemoteException;
    method public abstract int UninitGpio(int) throws android.os.RemoteException;
  }

  public static abstract class IMoyuManager.Stub extends android.os.Binder implements com.moyu.api.IMoyuManager {
    ctor public IMoyuManager.Stub();
    method public android.os.IBinder asBinder();
    method public static com.moyu.api.IMoyuManager asInterface(android.os.IBinder);
    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
  }

}

注册服务

framework/base/core/java/android/app/ContextImp.java

import com.moyu.api.MoyuManager;
import com.moyu.api.IMoyuManager;
...
        registerService(MOYU_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(MOYU_SERVICE);
                    IMoyuManager service = IMoyuManager.Stub.asInterface(b);
                    return new MoyuManager(service, ctx.mMainThread.getHandler());
                 }});

Context中添加字段

frameworks/base/core/java/android/content/Context.java

public static final String MOYU_SERVICE = "moyu";

添加源码文件

frameworks/base/core/java/com下新建目录moyu/api


package com.moyu.api;

import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;

public class MoyuManager {
	
	private final IMoyuManager mService;

    private Handler mHandler;
    private static final String TAG = "MoyuManager";
	
    public MoyuManager(IMoyuManager service, Handler handler) 
	{
        mHandler = handler;
        mService = service;
    }   

	public int InitGpio(int gpio, int dir)
	{
		try{
			return mService.InitGpio(gpio,dir);
		}catch (RemoteException e){
			Log.e(TAG, "InitGpio failed");
			return -1;
		}
	}

        public int UninitGpio(int fd)
        {
                try{
                        return mService.UninitGpio(fd);
                }catch (RemoteException e){
                        Log.e(TAG, "UninitGpio failed");
                        return -1;
                }
        }

        public int SetGpioValue(int fd, int value)
        {
                try{
                        return mService.SetGpioValue(fd, value);
                }catch (RemoteException e){
                        Log.e(TAG, "SetGpioValue failed");
                        return -1;
                }
        }


        public int GetGpioValue(int fd)
        {
                try{
                        return mService.GetGpioValue(fd);
                }catch (RemoteException e){
                        Log.e(TAG, "GetGpioValue failed");
                        return -1;
                }
        }
}

package com.moyu.api;

interface IMoyuManager
{
        int InitGpio(int gpio, int dir);
        int UninitGpio(int fd);
        int SetGpioValue(int fd, int value);
        int GetGpioValue(int fd);
}

启动服务

/frameworks/base/services/java/com/android/server/SystemServer.java
startOtherServices()中添加启动代码

try {
         Slog.i(TAG, "MoyuService");
                            
         mSystemServiceManager.startService("com.moyu.server.MoyuService");
     }catch (Throwable e) {
           reportWtf("start MoyuService error ", e);
     }

编写Service源代码

/framework/opt/下新建vendor/moyu目录,在vendor/moyu下新建Android.mk、jni、java目录以及文件
Android.mk

# Copyright (C) 2014 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)

# Build the java code
# ============================================================
LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast
LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
LOCAL_CPPFLAGS += -Wno-conversion-null

include $(CLEAR_VARS)

LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java
LOCAL_SRC_FILES := $(call all-java-files-under, java) \
	$(call all-Iaidl-files-under, java) \
	$(call all-logtags-files-under, java)

LOCAL_JAVA_LIBRARIES := services
LOCAL_MODULE := moyu-service

include $(BUILD_JAVA_LIBRARY)

#========================================================
include $(CLEAR_VARS)

LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast
LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
LOCAL_CPPFLAGS += -Wno-conversion-null

LOCAL_SRC_FILES := \
        jni/com_moyu_server_MoyuNative.cpp
LOCAL_SHARED_LIBRARIES := \
        libandroid_runtime\
        libz \
        libcutils \
        libutils \
        libbinder \
        libnetutils \

LOCAL_MODULE := libmoyu-jni

include $(BUILD_SHARED_LIBRARY)

com_moyu_server_MoyuNative.cpp


#define LOG_TAG "com_moyu_server_MoyuNative"

#include "jni.h"
#include <utils/misc.h>
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <cutils/properties.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <poll.h>

#define LOGD ALOGD
#define LOGE ALOGE
#define LOGV ALOGV

#define GPIOSET_PATH 		"/dev/ugpio"

//gpio ctr
#define IOCTRL_GPIO_INIT 			0x4c434b06
#define IOCTRL_SET_GPIO_VALUE	0x4c434b07
#define IOCTRL_GET_GPIO_VALUE	0x4c434b08

typedef struct
{
	unsigned short gpio_num;
	unsigned char gpio_cfg;//0 input 1 output (0~7)
	unsigned char gpio_pull;//PULL_DISABLE,PULL_UP,PULL_DOWN
	unsigned char gpio_driver;//0~3
}GPIO_CFG;

namespace android {

//gpio 
static jint InitGpio(JNIEnv* env, jobject clazz, jint gpio, jint dir)
{
	int result;
	GPIO_CFG gpio_cfg;
	int gpio_fd = open(GPIOSET_PATH, O_RDWR);
	if (gpio_fd < 0)
	{
		LOGE("open /dev/ugpio failed");
		return -1;
	}
	memset(&gpio_cfg,0,sizeof(GPIO_CFG));
	gpio_cfg.gpio_num= gpio;
	gpio_cfg.gpio_cfg = dir;
	if(ioctl(gpio_fd , IOCTRL_GPIO_INIT, &gpio_cfg))
	{
		LOGE("IOCTRL_GPIO_INIT  fail");
		return -1;
	}
	return gpio_fd;
}

static int UninitGpio(JNIEnv* env, jobject clazz,jint fd)
{
	close(fd);
	return 0;
}

static jint SetGpioValue(JNIEnv* env, jobject clazz,jint fd ,jint value)
{
	char data=value;
	if(ioctl(fd, IOCTRL_SET_GPIO_VALUE, &data))
	{
		LOGE("IOCTRL_SET_GPIO_VALUE  fail");
		return -1;
	}
	else
		return 0;
}
static jint GetGpioValue(JNIEnv* env, jobject clazz,jint fd)
{
	unsigned char data;
	if(ioctl(fd,IOCTRL_GET_GPIO_VALUE,&data))
	{
		LOGE("IOCTRL_SET_GPIO_VALUE  fail");
		return -1;
	}
	return data;
}
//gpio end


/*
 * JNI registration.
 */
static JNINativeMethod gMoyuMethods[] = {
	{"InitGpio",                 "(II)I",                      (void *)InitGpio },
	{"UninitGpio",               "(I)I",                       (void *)UninitGpio },
	{"SetGpioValue",             "(II)I",                      (void *)SetGpioValue },
	{"GetGpioValue",             "(I)I",                       (void *)GetGpioValue },
	   
};

#if 0
int register_com_moyu_server_MoyuNative(JNIEnv* env)
{
    return AndroidRuntime::registerNativeMethods(env, "com/moyu/server/MoyuNative", gMoyuMethods, NELEM(gMoyuMethods) );
}
#endif

/* User to register native functions */
extern "C"
jint Java_com_moyu_server_MoyuNative_registerNatives(JNIEnv* env, jclass clazz) {
   return AndroidRuntime::registerNativeMethods(env, "com/moyu/server/MoyuNative", gMoyuMethods, NELEM(gMoyuMethods) );
}
	
}

com.moyu.server.MoyuNative.java


package com.moyu.server;

class MoyuNative {

    static {
        System.loadLibrary("moyu-jni");
        registerNatives();
    }

    MoyuNative() {
   
    }
	public native static int registerNatives();
	public native static int InitGpio(int gpio, int dir);
	public native static int UninitGpio(int fd);
	public native static int SetGpioValue(int fd, int value);
	public native static int GetGpioValue(int fd);
}

com.moyu.server.MoyuService.java


package com.moyu.server;

import android.content.Context;
import android.util.Log;
import com.android.server.SystemService;

public final class MoyuService extends SystemService {

    private static final String TAG = "MoyuService";
    final MoyuServiceImpl mImpl;

    public MoyuService(Context context) {
        super(context);
        mImpl = new MoyuServiceImpl(context);
    }

    @Override
    public void onStart() {
        Log.i(TAG, "Registering service " + Context.MOYU_SERVICE);
        publishBinderService(Context.MOYU_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.start();
        }
    }
}

com.moyu.server.MoyuServiceImpl.java

package com.moyu.server;

import android.util.Log;
import android.content.Context;
import com.moyu.api.IMoyuManager;

public class MoyuServiceImpl extends IMoyuManager.Stub {
    private static final String TAG = "MoyuServiceImpl";
    public Context mContext;
    private final MoyuNative mNative;

    public MoyuServiceImpl(Context context) {
         Log.i(TAG, "Creating MoyuImpl");
         mContext=context;
		 mNative=new MoyuNative();
    }

    public void start() 
    {
        Log.i(TAG, "Starting Moyu  service");       
    }

	public int InitGpio(int gpio, int dir)
	{
		return mNative.InitGpio(gpio,dir);
	}
	public int UninitGpio(int fd)
	{
		return mNative.UninitGpio(fd);
	}
	public int SetGpioValue(int fd, int value)
	{
		return mNative.SetGpioValue(fd,value);
	}
	public int GetGpioValue(int fd)
	{
		return mNative.GetGpioValue(fd);
	}
}

至此从新编译烧录,可将framework.jar提取到项目中使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值