Android驱动开发-----给上层app提供一个iic接口服务,让主芯片发送iic指令控制外围电路。
- framework层。
在目录android\frameworks\base\services\java\com\android\server之下,新建一个服务
取名 :IICService.java
package com.android.server;
import android.content.Context;
import android.os.IIICService;
import android.util.Slog;
public class IICService extends IIICService.Stub{
private static final String TAG = "IICService";
IICService() {
init_native(0x51); //外围ic的iic地址
}
public void setVal(char[] send_data, int length) {
setVal_native(send_data, length);
}
public int getVal(int Reg_addr, int length) {
return getVal_native(Reg_addr, length);
}
public void iic_open(int slaveAddr)
{
init_native(slaveAddr);
}
public void iic_close()
{
iicclose_native();
}
private static native boolean init_native(int slaveAddr);
private static native void setVal_native(char[] send_data, int length);
private static native int getVal_native(int Reg_addr, int length);
private static native void iicclose_native();
};
2.jni层
在android\frameworks\base\services\jni创建一个文件,com_android_server_IICService.cpp在该文件中直接调用iic,略去了hardware
driver层。。。
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <cutils/log.h>
#include <hardware/hardware.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define I2C_RETRIES 0x0701 /* number of times a device address should be polled when not acknowledging */
#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms *//* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses * are NOT supported! (due to code brokenness) */
#define I2C_SLAVE 0x0703 /* Use this slave address */
#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
namespace android
{
int fd;
static void iic_setVal(JNIEnv* env, jobject clazz, jcharArray send_data, jint length)
{
if(fd == -1) {
ALOGE("iic JNI: device is not open.\n");
return;
}
unsigned short *psdata = env->GetCharArrayElements(send_data, NULL);
unsigned char *s_data = (unsigned char*)malloc(length);
for(int i=0; i<length; i++)
{
s_data[i] = psdata[i];
}
write(fd, s_data, length);
free(s_data);
env->ReleaseCharArrayElements(send_data, psdata, 0);
}
static int iic_getVal(JNIEnv* env, jobject clazz, jint Reg_addr, jint length) {
unsigned char s_data[2] = {0x00, 0x00}; //发送给外围ic的iic指令
unsigned char recv[20] = {0}; //读会数据
int res;
if(fd == -1) {
ALOGE("iic JNI: device is not open.\n");
return -1;
}
s_data[3] = Reg_addr;
res = write(fd, s_data, length);
res = read(fd, recv, 20);
return 0;
}
static int iic_device_open(int slaveAddr) {
int res;
fd = open("/dev/i2c-0",O_RDWR); //外围与主芯片连接的iic
if(fd < 0)
{
ALOGE("*iic JNI: device is not open.\n");
return fd;
}
res = ioctl(fd, I2C_RETRIES, 10);
res = ioctl(fd, I2C_TIMEOUT, 8);
res = ioctl(fd, I2C_TENBIT, 0); //not 10bit
res = ioctl(fd, I2C_SLAVE, slaveAddr); //0x58 直接读写寄存器地址
return fd;
}
static jboolean iic_init(JNIEnv* env, jclass clazz, int slaveAddr) {
if(iic_device_open(slaveAddr) == 0) {
ALOGE("JNI: iic device is opening...\n");
return 1;
}
ALOGE("iic JNI: initializing......\n");
return 0;
}
static void iic_close(JNIEnv* env, jclass clazz) {
close(fd);
}
static const JNINativeMethod method_table[] = {
{"init_native", "(I)Z", (void*)iic_init},
{"setVal_native", "([CI)V", (void*)iic_setVal},
{"getVal_native", "(II)I", (void*)iic_getVal},
{"iicclose_native", "()V", (void*)iic_close},
};
int register_android_server_IICService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/IICService", method_table, NELEM(method_table));
}
};
3.jni同目录之下 onload.cpp应添加
int register_android_server_IICService(JNIEnv *env);
register_android_server_IICService(env);
编译后,app可直接调用IICService 服务了。