如何大连开发区盛和铁板烧i2c interface 烧入

Android平台读写i2c设备开发笔记二
14:56 297人阅读 (0)
在android开发和移植过程中,有时需要对某设备进行读写,但系统可能并未提供相应的服务。我们就需要自己开发硬件访问服务来控制设备。下面的例子是读写最简单的i2c设备eeprom的流程,
i2c的驱动编写有两种方式,一种是利用系统提供的i2c-dev.c来实现一个i2c适配器的设备文件,然后通过在应用层操作I2C适配器来控制I2C设备;另一种是为I2C从设备独立编写一个设备驱动,不需要i2c-dev.c文件。由于前者比较简单通用性强,我们采用前者来展开。
根据android层次划分,我们照例对开发分为如下几步:
添加HAL层接口模块访问设备
使用JNI在应用程序框架层添加服务访问接口
使用服务接口api开发应用程序
添加HAL层接口模块访问设备
首先确认物理设备正常。根据开发板说明书获知设备挂载在/dev/i2c-1上,检测到该设备的存在,则通用设备驱动正常。
eeprom设备为at24c**系列,根据说明书获知设备从地址为0x50,准备工作完毕。
编写hal层接口模块头文件iic.h
进入源码根目录下hardware/libhardware/include/hardware目录新建iic.h,代码如下:
#ifndef ANDROID_IIC_INTERFACE_H
#define ANDROID_IIC_INTERFACE_H
#include &hardware/hardware.h&
__BEGIN_DECLS
#define IIC_HARDWARE_MODULE_ID "iic"
struct iic_module_t {
struct hw_module_
struct iic_device_t {
struct hw_device_
int (*iic_write)(struct iic_device_t* dev, unsigned char* dataBuf,
unsigned short slaveAddr, unsigned short subAddr, int len);
int (*iic_read)(struct iic_device_t* dev, unsigned char* dataBuf,
unsigned short slaveAddr, int len);
__END_DECLS
#ifndef ANDROID_IIC_INTERFACE_H
#define ANDROID_IIC_INTERFACE_H
#include &hardware/hardware.h&
__BEGIN_DECLS
#define IIC_HARDWARE_MODULE_ID "iic"
struct iic_module_t {
struct hw_module_
struct iic_device_t {
struct hw_device_
int (*iic_write)(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, unsigned short subAddr, int len);
int (*iic_read)(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, int len);
__END_DECLS
这里定义了iic_write和iic_read两个接口,头文件按照hal规范编写。
2. 编写hal层接口模块文件
进入源码根目录下hardware/libhardware/modules目录新建iic目录,并在iic目录中添加iic.c,代码如下:
#include &hardware/hardware.h&
#include &hardware/iic.h&
#include &fcntl.h&
#include &errno.h&
#include &cutils/log.h&
#include &cutils/atomic.h&
#include &stdio.h&
#include&linux/i2c.h&
#include&linux/i2c-dev.h&
#include &stdlib.h&
#include &linux/types.h&
#include &unistd.h&
#include &sys/types.h&
#include &sys/ioctl.h&
#include &string.h&
#include &hardware/hardware.h&
#include &hardware/iic.h&
#include &fcntl.h&
#include &errno.h&
#include &cutils/log.h&
#include &cutils/atomic.h&
#include &stdio.h&
#include&linux/i2c.h&
#include&linux/i2c-dev.h&
#include &stdlib.h&
#include &linux/types.h&
#include &unistd.h&
#include &sys/types.h&
#include &sys/ioctl.h&
#include &string.h&
&SPAN style="FONT-SIZE: 14px"&#define
DEVICE_NAME "/dev/i2c-1"
#define MODULE_NAME "iic"
#define MODULE_AUTHOR ""
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_RDWR 0x0707
struct i2c_msg
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
unsigned char *
struct i2c_rdwr_ioctl_data {
struct i2c_msg *
static int iic_device_open(const struct hw_module_t* module, const
char* name, struct hw_device_t** device);
static int iic_device_close(struct hw_device_t* device);
static int iic_write(struct iic_device_t* dev, unsigned char*
dataBuf, unsigned short slaveAddr, unsigned short subAddr, int
static int iic_read(struct iic_device_t* dev, unsigned char*
dataBuf, unsigned short slaveAddr, int len);
static struct hw_module_methods_t iic_module_methods = {
open: iic_device_open
struct i2c_rdwr_ioctl_data iic_da
struct iic_module_t HAL_MODULE_INFO_SYM = {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: IIC_HARDWARE_MODULE_ID,
name: MODULE_NAME,
author: MODULE_AUTHOR,
methods: &iic_module_methods,
//实现了一个open的方法供jni层调用,从而实例化eeprom_device_t
static int iic_device_open(const struct hw_module_t* module, const
char* name, struct hw_device_t** device){
struct iic_device_t*
dev = (struct iic_device_t*)malloc(sizeof(struct
iic_device_t));
if(!dev) {
LOGE("iic Stub: failed to alloc space");
return -EFAULT;
LOGE("hal: alloc space succ!");
memset(dev, 0, sizeof(struct iic_device_t));
dev-&common.tag = HARDWARE_DEVICE_TAG;
dev-&common.version = 0;
dev-&common.module = (hw_module_t*)
dev-&common.close = iic_device_
dev-&iic_write = iic_
dev-&iic_read = iic_
*device = &dev-&
//将实例化后的iic_device_t地址返回给jni层,这样jni层就可以直接调用方法了。
if((dev-&fd = open(DEVICE_NAME, O_RDWR)) == -1)
LOGE("iic Stub hal: failed to open /dev/i2c-1 -- %s.",
strerror(errno));
free(dev);
return -EFAULT;
LOGI("iic Stub hal: open /dev/i2c-1 successfully.");
iic_data.nmsgs=2;
iic_data.msgs=(struct
i2c_msg*)malloc(iic_data.nmsgs*sizeof(struct
i2c_msg));
if(!iic_data.msgs){
LOGE("malloc error");
close(dev-&fd);
ioctl(dev-&fd, I2C_TIMEOUT,
2);//设置超时时间
ioctl(dev-&fd, I2C_RETRIES,
1);//设置重发次数
static int iic_device_close(struct hw_device_t* device) {
struct iic_device_t* iic_device = (struct
iic_device_t*)
if(iic_device) {
close(iic_device-&fd);
free(iic_device);
static int iic_write(struct iic_device_t* dev, unsigned char*
dataBuf, unsigned short slaveAddr, unsigned short subAddr, int len)
int count = 0;
unsigned char data[2];
LOGI("iic Stub hal: set value %s to device.", dataBuf);
iic_data.nmsgs=1;
(iic_data.msgs[0]).len=2;
//写入地址位和数据长度
(iic_data.msgs[0]).addr=slaveA// 设备地址0x50
(iic_data.msgs[0]).flags=0; //write
(iic_data.msgs[0]).buf=(unsigned char*)malloc(2);
while(count&len){
bytes = 0;
data[bytes++] = subA//先写子地址
data[bytes] = dataBuf[count];//再写value
LOGI("IIC write HAL: %x,%x", data[0],data[1]);
(iic_data.msgs[0]).buf=da//the data to
ret=ioctl(dev-&fd,I2C_RDWR,(unsigned
long)&iic_data);
if(ret&0){
LOGI("IIC HAL ioctl error");
subAddr++;
usleep(3000);//延迟3毫秒
LOGI("you have write %s into iic at %x address len: %d",dataBuf,
subAddr, len);
static int iic_read(struct iic_device_t* dev, unsigned char*
dataBuf, unsigned short slaveAddr, int len){
int count = 0;
iic_data.nmsgs=1;
(iic_data.msgs[0]).len=1;
(iic_data.msgs[0]).addr=slaveA // 设备地址
(iic_data.msgs[0]).flags=I2C_M_RD;//read
(iic_data.msgs[0]).buf=(unsigned char*)malloc(1);
while(count&len){
(iic_data.msgs[0]).buf= dataBuf++;
if(ioctl(dev-&fd,I2C_RDWR,(unsigned
long)&iic_data)&0){
LOGE("ioctl read error");
LOGI("IIC read HAL: %x", dataBuf[count]);
#define DEVICE_NAME "/dev/i2c-1"
#define MODULE_NAME "iic"
#define MODULE_AUTHOR ""
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_RDWR
struct i2c_msg
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
unsigned char *
struct i2c_rdwr_ioctl_data {
struct i2c_msg *
static int iic_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
static int iic_device_close(struct hw_device_t* device);
static int iic_write(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, unsigned short subAddr, int len);
static int iic_read(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, int len);
static struct hw_module_methods_t iic_module_methods = {
open: iic_device_open
struct i2c_rdwr_ioctl_data iic_da
struct iic_module_t HAL_MODULE_INFO_SYM = {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: IIC_HARDWARE_MODULE_ID,
name: MODULE_NAME,
author: MODULE_AUTHOR,
methods: &iic_module_methods, //实现了一个open的方法供jni层调用,从而实例化eeprom_device_t
static int iic_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device){
struct iic_device_t*
dev = (struct iic_device_t*)malloc(sizeof(struct iic_device_t));
if(!dev) {
LOGE("iic Stub: failed to alloc space");
return -EFAULT;
LOGE("hal: alloc space succ!");
memset(dev, 0, sizeof(struct iic_device_t));
dev-&common.tag = HARDWARE_DEVICE_TAG;
dev-&common.version = 0;
dev-&common.module = (hw_module_t*)
dev-&common.close = iic_device_
dev-&iic_write = iic_
dev-&iic_read = iic_
*device = &dev-&
//将实例化后的iic_device_t地址返回给jni层,这 jni层就可以直接调用方法了。
if((dev-&fd = open(DEVICE_NAME, O_RDWR)) == -1) {
LOGE("iic Stub hal: failed to open /dev/i2c-1 -- %s.", strerror(errno));
free(dev);
return -EFAULT;
LOGI("iic Stub hal: open /dev/i2c-1 successfully.");
iic_data.nmsgs=2;
iic_data.msgs=(struct i2c_msg*)malloc(iic_data.nmsgs*sizeof(struct i2c_msg));
if(!iic_data.msgs){
LOGE("malloc error");
close(dev-&fd);
ioctl(dev-&fd, I2C_TIMEOUT, 2);//设置超时时间
ioctl(dev-&fd, I2C_RETRIES, 1);//设置重发次数
static int iic_device_close(struct hw_device_t* device) {
struct iic_device_t* iic_device = (struct iic_device_t*)
if(iic_device) {
close(iic_device-&fd);
free(iic_device);
static int iic_write(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, unsigned short subAddr, int len) {
int count = 0;
unsigned char data[2];
LOGI("iic Stub hal: set value %s to device.", dataBuf);
iic_data.nmsgs=1;
(iic_data.msgs[0]).len=2; //写入地址位和数据长度
(iic_data.msgs[0]).addr=slaveA// 设备地址0x50
(iic_data.msgs[0]).flags=0; //write
(iic_data.msgs[0]).buf=(unsigned char*)malloc(2);
while(count&len){
bytes = 0;
data[bytes++] =
subA//先写子地址
data[bytes]
= dataBuf[count];//再写value
LOGI("IIC write HAL: %x,%x", data[0],data[1]);
(iic_data.msgs[0]).buf=da//the data to write
ret=ioctl(dev-&fd,I2C_RDWR,(unsigned long)&iic_data);
if(ret&0){
LOGI("IIC HAL ioctl error");
subAddr++;
usleep(3000);//延迟3毫秒
LOGI("you have write %s into iic at %x address len: %d",dataBuf, subAddr, len);
static int iic_read(struct iic_device_t* dev, unsigned char* dataBuf, unsigned short slaveAddr, int len){
int count = 0;
iic_data.nmsgs=1;
(iic_data.msgs[0]).len=1;
(iic_data.msgs[0]).addr=slaveA //
(iic_data.msgs[0]).flags=I2C_M_RD;//read
(iic_data.msgs[0]).buf=(unsigned char*)malloc(1);
while(count&len){
(iic_data.msgs[0]).buf= dataBuf++;
if(ioctl(dev-&fd,I2C_RDWR,(unsigned long)&iic_data)&0){
LOGE("ioctl read error");
LOGI("IIC read HAL: %x", dataBuf[count]);
注意:需打开设备/dev/i2c-1权限,否则会碰到Pemission
Denied错误。从源码根目录下进入system/core/rootdir目录,打开ueventd.rc
添加一行:/dev/i2c-1 0666 root root
(这里设备各开发板可能不同)
在iic目录下编写android.mk进行编译
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SRC_FILES := iic.c
LOCAL_MODULE := iic.default
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SRC_FILES := iic.c
LOCAL_MODULE := iic.default
include $(BUILD_SHARED_LIBRARY)
编译命令:mmm -B
hardware/libhardware/module/iic
编译成功会得到iic.default.so,打包进img默认会被加载。
16:43 758人阅读 (0)
使用JNI在应用程序框架层添加服务访问接口
APP应用不能直接访问HAL层,需要JNI层访问HAL模块并向上提供API接口。可以直接提供接口,但建议最好使用服务的方式提供访问。
我们先看JNI如何访问刚才的HAL模块。
进入源码根目录下的frameworks/base/service/jni目录,新建com_android_server_IICService.cpp,代码如下:
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include &utils/misc.h&
#include &cutils/log.h&
#include &hardware/hardware.h&
#include &hardware/iic.h&
#include &stdio.h&
namespace android
struct iic_device_t* iic_device = NULL;
static void iic_setVal(JNIEnv* env, jobject clazz, jstring val,
jint slaveAddr, jint subAddr, jint len) {
const char *str = env-&GetStringUTFChars(val,
LOGI("iic JNI: set value %s to device.", str);
if(!iic_device) {
LOGI("iic JNI: device is not open.");
iic_device-&iic_write(iic_device, (unsigned
char*)str, slaveAddr, subAddr, len);
env-&ReleaseStringUTFChars(val, str);
//注意释放资源
static jstring iic_getVal(JNIEnv* env, jobject clazz, jint
slaveAddr, jint len) {
unsigned char* data = (unsigned char*)malloc(len);
iic_device-&iic_read(iic_device, data,
slaveAddr, len);
if(!iic_device) {
LOGI("iic JNI: device is not open.");
int i = 0;
for(;i&strlen((const char*)data);i++){
LOGI("data: %c ", data[i]);
//LOGI("iic JNI: get value %s from device @ %x address!",
data, subAddr);
jstring tmp = env-&NewStringUTF((const
char*)data);
free(data);
data = NULL;
static inline int iic_device_open(const hw_module_t* module, struct
iic_device_t** device) {
return module-&methods-&open(module,
IIC_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
static jboolean iic_init(JNIEnv* env, jclass clazz) {
iic_module_t*
LOGI("iic JNI: initializing......");
if(hw_get_module(IIC_HARDWARE_MODULE_ID, (const struct
hw_module_t**)&module) == 0) {
LOGI("iic JNI: iic Stub found.");
if(iic_device_open(&(module-&common),
&iic_device) == 0) {
LOGI("eeprom JNI: iic device is opening...");
LOGE("eeprom JNI: failed to open iic device.");
return -1;
LOGE("eeprom JNI: failed to get iic stub module.");
return -1;
static const JNINativeMethod method_table[] = {
{"init_native", "()Z", (void*)iic_init},
{"setVal_native", "(Ljava/lang/SIII)V",
(void*)iic_setVal},
{"getVal_native", "(III)Ljava/lang/S",
(void*)iic_getVal},
int register_android_server_IICService(JNIEnv *env) {
return jniRegisterNativeMethods(env,
"com/android/server/IICService", method_table,
NELEM(method_table));
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include &utils/misc.h&
#include &cutils/log.h&
#include &hardware/hardware.h&
#include &hardware/iic.h&
#include &stdio.h&
namespace android
struct iic_device_t* iic_device = NULL;
static void iic_setVal(JNIEnv* env, jobject clazz, jstring val, jint slaveAddr, jint subAddr, jint len) {
const char *str = env-&GetStringUTFChars(val, NULL);
LOGI("iic JNI: set value %s to device.", str);
if(!iic_device) {
LOGI("iic JNI: device is not open.");
iic_device-&iic_write(iic_device, (unsigned char*)str, slaveAddr, subAddr, len);
env-&ReleaseStringUTFChars(val, str);
//注意释放资源
static jstring iic_getVal(JNIEnv* env, jobject clazz, jint slaveAddr, jint len) {
unsigned char* data = (unsigned char*)malloc(len);
iic_device-&iic_read(iic_device, data, slaveAddr, len);
if(!iic_device) {
LOGI("iic JNI: device is not open.");
int i = 0;
for(;i&strlen((const char*)data);i++){
LOGI("data: %c ", data[i]);
//LOGI("iic JNI: get value %s from device @ %x address!", data, subAddr);
jstring tmp = env-&NewStringUTF((const char*)data);
free(data);
data = NULL;
static inline int iic_device_open(const hw_module_t* module, struct iic_device_t** device) {
return module-&methods-&open(module, IIC_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
static jboolean iic_init(JNIEnv* env, jclass clazz) {
iic_module_t*
LOGI("iic JNI: initializing......");
if(hw_get_module(IIC_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
LOGI("iic JNI: iic Stub found.");
if(iic_device_open(&(module-&common), &iic_device) == 0) {
LOGI("eeprom JNI: iic device is opening...");
LOGE("eeprom JNI: failed to open iic device.");
return -1;
LOGE("eeprom JNI: failed to get iic stub module.");
return -1;
static const JNINativeMethod method_table[] = {
{"init_native", "()Z", (void*)iic_init},
{"setVal_native", "(Ljava/lang/SIII)V", (void*)iic_setVal},
{"getVal_native", "(III)Ljava/lang/S", (void*)iic_getVal},
int register_android_server_IICService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/IICService", method_table, NELEM(method_table));
然后需要让android启动时加载此jni模块
在同目录下修改onload.cpp:
在namespace android中添加一行
int register_android_server_IICService(JNIEnv *env);
在JNI_onLoad方法中添加一行
register_android_server_IICService(env);
在同目录下修改Android.mk:
LOCAL_SRC_FILES增加一行
com_android_server_IICService \
编译命令:mmm
frameworks/base/services/jni
HAL是根据iic_init中的IIC_HARDWARE_MODULE_ID加载相应模块。
根据jni规则我们知道这里存在一个调用jni的java服务类:com.android.server.IICService
位置为:frameworks/base/services/java/com/android/server
代码如下:
package com.android.
import android.content.C
import android.os.IIICS
import android.util.S
public class IICService extends IIICService.Stub {
private static final String TAG = "IICService";
IICService() {
init_native();
public void setVal(String val,int slaveAddr, int regAddr, int len)
setVal_native(val, slaveAddr, regAddr, len);
public String getVal(int slaveAddr,int len) {
return getVal_native( slaveAddr, len);
//本地方法
private static native boolean init_native();
private static native void setVal_native(String val, int slaveAddr,
int regAddr, int len);
private static native String getVal_native(int slaveAddr, int
package com.android.
import android.content.C
import android.os.IIICS
import android.util.S
public class IICService extends IIICService.Stub {
private static final String TAG = "IICService";
IICService() {
init_native();
public void setVal(String val,int slaveAddr, int regAddr, int len) {
setVal_native(val, slaveAddr, regAddr, len);
public String getVal(int slaveAddr,int len) {
return getVal_native( slaveAddr, len);
//本地方法
private static native boolean init_native();
private static native void setVal_native(String val, int slaveAddr, int regAddr, int len);
private static native String getVal_native(int slaveAddr, int len);
从代码中我们可以看到它继承了IIICService.Stub,因为硬件访问一般需要放在一个独立的线程中,这里使用了代理的方法来处理app与硬件服务的通信。
我们需要在frameworks/base/core/java/android/os中新建IIICService.aidl(注意是III)
package android.
interface IIICService {
void setVal(String val, int slaveAddr, int regAddr, int len);
String getVal(int slaveAddr, int len);
它定义了服务的接口,接口在IICService中实现并关联到jni方法中。
同时我们需要修改frameworkd/base下的Android.mk编译文件,在LOCAL_SRC_FILES中增加
core/java/android/os/IIICService.aidl
编译命令: mmm frameworks/base
最后需要把新增的IICService服务加入到ServiceManager中,这样就可以通过ServiceManager进行调用。
修改frameworks/base/services/java/com/android/server下的SystemServer.java
在run()方法中添加
Slog.i(TAG, "IIC SERVICE");
ServiceManager.addService("iic", new
IICService());
}catch(Throwable e){
Slog.e(TAG, "Failure starting IIC
Service", e);
编译命令:mmm frameworks/base/services/java
注意:有可能会编译不通过,因为这里修改了android的官方api,
需要运行make
update-api更新frameworks/base/api/current.xml
打包后,app就可以使用IICService接口来访问硬件了。
下一节发上app相关代码
17:06 677人阅读 (0)
三、app调用服务接口访问硬件
上主要代码EEPROMActivity.java
package com.zkgd.
import android.app.A
import android.os.B
import android.os.ServiceM
import android.os.IIICS
import android.os.RemoteE
import android.util.L
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import android.widget.EditT
public class EEPROMActivity extends Activity implements
OnClickListener{
private final static String LOG_TAG = "com.zkgd.eeprom";
private IIICService iicService =
private EditText valueText =
private Button readButton =
private Button writeButton =
private Button clearButton =
int len = 1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iicService = IIICService.Stub.asInterface(
ServiceManager.getService("iic"));
valueText = (EditText)findViewById(R.id.edit_value);
readButton = (Button)findViewById(R.id.button_read);
writeButton = (Button)findViewById(R.id.button_write);
clearButton = (Button)findViewById(R.id.button_clear);
readButton.setOnClickListener(this);
writeButton.setOnClickListener(this);
clearButton.setOnClickListener(this);
Log.i(LOG_TAG, "Activity Created");
public void onClick(View v) {
if(v.equals(readButton)) {
//在从设备中读取数据
String val = iicService.getVal(0x50,len);
valueText.setText(val);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while reading value from
device.");
else if(v.equals(writeButton)) {
String val = valueText.getText().toString();
len = val.length();
//在从设备的子地址处开始写入数据
iicService.setVal(val,0x50,0x10,len);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while writing value to
device.");
else if(v.equals(clearButton)) {
String text = "";
valueText.setText(text);
package com.zkgd.
import android.app.A
import android.os.B
import android.os.ServiceM
import android.os.IIICS
import android.os.RemoteE
import android.util.L
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import android.widget.EditT
public class EEPROMActivity extends Activity
implements OnClickListener{
private final static String LOG_TAG = "com.zkgd.eeprom";
private IIICService iicService =
private EditText valueText =
private Button readButton =
private Button writeButton =
private Button clearButton =
int len = 1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iicService = IIICService.Stub.asInterface(
ServiceManager.getService("iic"));
valueText = (EditText)findViewById(R.id.edit_value);
readButton = (Button)findViewById(R.id.button_read);
writeButton = (Button)findViewById(R.id.button_write);
clearButton = (Button)findViewById(R.id.button_clear);
readButton.setOnClickListener(this);
writeButton.setOnClickListener(this);
clearButton.setOnClickListener(this);
Log.i(LOG_TAG, "Activity Created");
public void onClick(View v) {
if(v.equals(readButton)) {
//在从设备中读取数据
String val =
iicService.getVal(0x50,len);
valueText.setText(val);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while reading value from device.");
else if(v.equals(writeButton)) {
String val = valueText.getText().toString();
len = val.length();
//在从设备的子地址处开始写入数据
iicService.setVal(val,0x50,0x10,len);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while writing value to device.");
else if(v.equals(clearButton)) {
String text = "";
valueText.setText(text);
工程eeprom放置在源码目录package/app/下
编译命令:mmm
package/app/eeprom
打包,烧写固件至开发板,启动就可以看到该应用的图标了。
整个调用流程为:app---&framework层服务---&JNI本地接口---&HAL---&硬件
一个问题,这种方法改动了android原生api,移植通用性不好。如果想做通用app,可以考虑NDK源码开发,底层功能打包成库文件进行调用,又可分为eclipse开发和源码环境开发,推荐源码环境下开发,eclipse老是报缺这缺那的,在源码环境下只要把Android.mk文件写好,基本不会报找不到包找不到方法等错误。
另一个问题,硬件访问会遭遇到权限问题。如果做通用app,需要设备root了,然后在代码里添加权限修改操作,如:"chmod
777 "+getPackageCodePath(); "chmod 777 /dev/i2c-1";
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 烟台开发区烧伤 的文章

 

随机推荐