参考链接:http://blog.csdn.net/sweetsnow24/article/details/8634183
参考链接:http://blog.csdn.net/sweetsnow24/article/details/8634183
我的实现:
1.定义Native方法:
public class WakeUp {
static {
System.loadLibrary("WakeUp");
}
public static native int open(String path, int oFlag);
public static native int getWakeUpState(int fid);
public static native int getWakeUpDegree();
public static native int close(int fId);
}
2.生成.h头文件
生成方法:进入项目文件夹, 生成JNI的头文件, 使用命令:
javah -classpath bin/classes -d jni com.robot.et.core.hardware.wakeup.WakeUp
生成后的头文件(com_robot_et_core_hardware_wakeup_WakeUp.h)如下:
/* DO NOT EDIT THIS FILE - it is machine generated *
/#include
/* Header for class com_robot_et_core_hardware_wakeup_WakeUp */
#ifndef _Included_com_robot_et_core_hardware_wakeup_WakeUp
#define _Included_com_robot_et_core_hardware_wakeup_WakeUp
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_robot_et_core_hardware_wakeup_WakeUp
* Method: open
* Signature: (Ljava/lang/String;I)Ljava/io/FileDescriptor;
*/
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_open
(JNIEnv *, jobject, jstring, jint);
/*
* Class: com_robot_et_core_hardware_wakeup_WakeUp
* Method: getWakeUpState
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_getWakeUpState
(JNIEnv *, jobject,jint);
/*
* Class: com_robot_et_core_hardware_wakeup_WakeUp
* Method: getWakeUpDegree
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_getWakeUpDegree
(JNIEnv *, jobject);
/*
* Class: com_robot_et_core_hardware_wakeup_WakeUp
* Method: close
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_close
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
3.具体实现(.cpp文件)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "i2c-dev.h"
#include
#include "com_robot_et_core_hardware_wakeup_WakeUp.h"
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************
* Constants
****************************************************************/
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define MAX_BUF 64
#define GPIO_C4 (68)
#define WAKEUP_SUCCESS (0)
#define WAKEUP_FAIL (-1)
#define I2C_FILE_OPEN_ERR (-2)
#define REGISTER_SLAVE_ERR (-3)
#define SOUND_LOCALIZATION_OCCUR (1)
unsigned int i2c_fileId;
int gpio_fileId;
unsigned int wakeup_degree;
/****************************************************************
* gpio_export
****************************************************************/
int gpio_export(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/****************************************************************
* gpio_unexport
****************************************************************/
int gpio_unexport(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/****************************************************************
* gpio_set_dir
****************************************************************/
int gpio_set_dir(unsigned int gpio, unsigned int out_flag)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/direction");
return fd;
}
if (out_flag)
write(fd, "out", 4);
else
write(fd, "in", 3);
close(fd);
return 0;
}
/****************************************************************
* gpio_set_value
****************************************************************/
int gpio_set_value(unsigned int gpio, unsigned int value)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-value");
return fd;
}
if (value)
write(fd, "1", 2);
else
write(fd, "0", 2);
close(fd);
return 0;
}
/****************************************************************
* gpio_get_value
****************************************************************/
int gpio_get_value(unsigned int gpio, unsigned int *value)
{
int fd, len;
char buf[MAX_BUF];
char ch;
len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_RDONLY);
if (fd < 0) {
perror("gpio/get-value");
return fd;
}
read(fd, &ch, 1);
if (ch != '0') {
*value = 1;
} else {
*value = 0;
}
close(fd);
return 0;
}
/****************************************************************
* gpio_set_edge
****************************************************************/
int gpio_set_edge(unsigned int gpio, char *edge)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/edge", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-edge");
return fd;
}
write(fd, edge, strlen(edge) + 1);
close(fd);
return 0;
}
/****************************************************************
* gpio_fd_open
****************************************************************/
int gpio_fd_open(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_RDONLY | O_NONBLOCK );
if (fd < 0) {
perror("gpio/fd_open");
}
return fd;
}
/****************************************************************
* gpio_fd_close
****************************************************************/
int gpio_fd_close(int fd)
{
return close(fd);
}
#define xfm20512_ADDR (0x47)
#define I2C_BUF_LEN (256)
#define DELAY_MS(ms) usleep((ms) * 1000)
/*****************************************************************************
函 数 名 : i2c_write_proc
功能描述 : i2c_write_proc
输入参数 : int fd
unsigned char addr
unsigned char reg
unsigned char *val
unsigned char len
输出参数 : 无
返 回 值 : static
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2016年6月12日
作 者 : zlg
修改内容 : 新生成函数
*****************************************************************************/
static int i2c_write_proc
(
int fd,
unsigned char addr,
unsigned char reg,
unsigned char *val,
unsigned char len
)
{
unsigned char buf[I2C_BUF_LEN];
struct i2c_rdwr_ioctl_data cmd;
struct i2c_msg msg[1];
memset(buf, 0, sizeof(buf)); // zero memset buffer
buf[0] = reg; // The first byte indicates which register we'll write
memcpy(&buf[1], val, len); // The last bytes indicates the values to write
/* Construct the i2c_msg struct */
msg[0].addr = addr; // Device address
msg[0].flags = 0; // Write option
msg[0].len = len + 1; // Include register byte
msg[0].buf = buf; // Data buffer
/* Construct the i2c_rdwr_ioctl_data struct */
cmd.msgs = msg; // Message
cmd.nmsgs = sizeof(msg) / sizeof(struct i2c_msg);
/* Transfer the i2c command packet to the kernel and verify it worked */
if (ioctl(fd, I2C_RDWR, &cmd) < 0)
{
printf("Unable to send data!\n");
return 1;
}
return 0;
}
/*****************************************************************************
函 数 名 : i2c_read_proc
功能描述 : i2c_read_proc
输入参数 : int fd
unsigned char addr
unsigned char reg
unsigned char *val
unsigned char len
输出参数 : 无
返 回 值 : static
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2016年6月12日
作 者 : zlg
修改内容 : 新生成函数
*****************************************************************************/
static int i2c_read_proc
(
int fd,
unsigned char addr,
unsigned char reg,
unsigned char *val,
unsigned char len
)
{
struct i2c_rdwr_ioctl_data cmd;
struct i2c_msg msg[2];
msg[0].addr = addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = ®
msg[1].addr = addr;
msg[1].flags = I2C_M_RD /* | I2C_M_NOSTART*/;
msg[1].len = len;
msg[1].buf = val;
/* Construct the i2c_rdwr_ioctl_data struct */
cmd.msgs = msg;
cmd.nmsgs = sizeof(msg) / sizeof(struct i2c_msg);
/* Send the request to the kernel and get the result back */
if (ioctl(fd, I2C_RDWR, &cmd) < 0)
{
printf("Unable to send data!\n");
return -1;
}
return 0;
}
/*****************************************************************************
函 数 名 : xfm20512_get_version
功能描述 : xfm20512_get_version
输入参数 : int fd
unsigned int *version
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2016年6月12日
作 者 : zlg
修改内容 : 新生成函数
*****************************************************************************/
int xfm20512_get_version(int fd, unsigned int *version)
{
unsigned int data = 0x00000F00;
/* 1. Send version query command */
if (i2c_write_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, 4))
return -1;
DELAY_MS(1); // Delay 1ms at least
/* 2. Query command status */
do {
if (i2c_read_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, 4))
return -1;
DELAY_MS(1); // Delay 1ms at least
} while (0x00020001 != data);
if (i2c_read_proc(fd, xfm20512_ADDR, 0x01, (unsigned char *)version, 8))
return -1;
return 0;
}
/*****************************************************************************
函 数 名 : xfm20512_get_degree
功能描述 : xfm20512_get_degree
输入参数 : int fd
unsigned int *degree
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2016年6月12日
作 者 : zlg
修改内容 : 新生成函数
*****************************************************************************/
int xfm20512_get_degree(int fd, unsigned int *degree)
{
unsigned int data = 0x00001000;
/* 1. Send degree query command */
if (i2c_write_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, 4))
return -1;
DELAY_MS(1); // Delay 1ms at least
/* 2. Query command status */
do {
if (i2c_read_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, 4))
return -1;
DELAY_MS(1); // Delay 1ms at least
} while (0x00010001 != data);
/* 3. Read wakeup degree */
if (i2c_read_proc(fd, xfm20512_ADDR, 0x01, (unsigned char *)degree, 4))
return -1;
return 0;
}
int xfm20512_enter_wakeup(int fd)
{
unsigned int data = 0x00001100;
/* 1. Send enter wakeup command */
if (i2c_write_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, sizeof(unsigned int)))
return -1;
DELAY_MS(1); // Delay 1ms at least
/* 2. Query command status */
do {
if (i2c_read_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, sizeof(unsigned int)))
return -1;
DELAY_MS(1); // Delay 1ms at least
} while (0x00000001 != data);
return 0;
}
int xfm20512_exit_wakeup(int fd, unsigned int beam)
{
unsigned int data = 0x00001200 | ((beam & 0x3) << 16);
/* 1. Send exit wakeup command */
if (i2c_write_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, sizeof(unsigned int)))
return -1;
DELAY_MS(1); // Delay 1ms at least
/* 2. Query command status */
do {
if (i2c_read_proc(fd, xfm20512_ADDR, 0x00, (unsigned char *)&data, sizeof(unsigned int)))
return -1;
DELAY_MS(1); // Delay 1ms at least
} while (0x00030001 != data);
return 0;
}
/****************************************************************
* i2c_init
****************************************************************/
int i2c_init()
{
int fd = -1;
int ret;
int write_count = 0;
/* 打开master侧的I2C-0接口 */
i2c_fileId = open("/dev/i2c-0", O_RDWR);
if (i2c_fileId < 0)
{
printf("Open i2c-0 Port Error!\n");
return I2C_FILE_OPEN_ERR;
}
#if 0
/* 注册从机 */
if (ioctl(i2c_fileId, I2C_SLAVE, xfm20512_ADDR) < 0)
{
printf("ioctl error\n");
return REGISTER_SLAVE_ERR;
}
#endif
/* 查询模块版本信息 */
unsigned int version;
if (!xfm20512_get_version(i2c_fileId, &version))
{
printf("version = %d\n", version);
}
return WAKEUP_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_open
(JNIEnv *env, jobject obj, jstring path, jint oflag)
{
int gpio;
int ret;
/* i2c init */
ret = i2c_init();
if (ret < 0)
{
return ret;
}
system("setenforce 0");
system("chmod 777 /sys/class/gpio");
system("chmod 777 /sys/class/gpio/export");
system("echo 68 > /sys/class/gpio/export");
system("chmod 777 /sys/class/gpio/gpio68");
system("chmod 777 /sys/class/gpio/gpio68/direction");
system("chmod 777 /sys/class/gpio/gpio68/edge");
system("chmod 777 /sys/class/gpio/gpio68/value");
gpio = GPIO_C4;
gpio_export(gpio);
gpio_set_dir(gpio, 0);
gpio_set_edge(gpio, (char*)"rising");
gpio_fileId = gpio_fd_open(gpio);
if (gpio_fileId < 0)
{
return WAKEUP_FAIL;
}
return gpio_fileId;
}
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_getWakeUpState
(JNIEnv *env, jobject obj, jint wakeup_fd)
{
struct pollfd fdset[2];
int nfds = 2;
int timeout, rc;
char buf[MAX_BUF];
int len;
#if 0
while (1) {
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = STDIN_FILENO;
fdset[0].events = POLLIN;
fdset[1].fd = wakeup_fd;
fdset[1].events = POLLPRI;
rc = poll(fdset, nfds, 1000);
if (rc < 0) {
//printf("\npoll() failed!\n");
return -1;
}
if (rc == 0) {
printf(".");
return 0;
}
if (fdset[1].revents & POLLPRI) {
len = read(fdset[1].fd, buf, 1);
xfm20512_get_degree(i2c_fileId, &wakeup_degree);
return SOUND_LOCALIZATION_OCCUR;
}
if (fdset[0].revents & POLLIN) {
(void)read(fdset[0].fd, buf, 1);
}
fflush(stdout);
}
#endif
memset(buf, '\0', sizeof(buf));
#if 0
len = read(wakeup_fd, buf, 16);
if (strlen(buf) != 0)
{
xfm20512_get_degree(i2c_fileId, &wakeup_degree);
return 1;
}
#else
unsigned int value = 0;
(void)gpio_get_value(68, &value);
if (value != 0)
{
xfm20512_get_degree(i2c_fileId, &wakeup_degree);
while (value != 0)
{
(void)gpio_get_value(68, &value);
}
return 1;
}
#endif
return WAKEUP_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_getWakeUpDegree
(JNIEnv *env, jobject obj)
{
return wakeup_degree;
}
JNIEXPORT jint JNICALL Java_com_robot_et_core_hardware_wakeup_WakeUp_close
(JNIEnv *env, jobject obj, jint gpio_fileId)
{
close(gpio_fileId);
return WAKEUP_SUCCESS;
}
#ifdef __cplusplus
}
#endif
4.头文件i2c-dev.h(直接从Linux驱动中直接复制过来的)
/* i2c-dev.h - i2c-bus driver, char device interface Copyright (C) 1995-97 Simon G. Vogl Copyright (C) 1998-99 Frodo LooijaardThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.*/
#ifndef _LINUX_I2C_DEV_H
#define _LINUX_I2C_DEV_H
#include
#include
/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an
* unsigned long, except for:
* - I2C_FUNCS, takes pointer to an unsigned long
* - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
* - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
*/
#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_SLAVE_FORCE 0x0706 /* Use this slave address, even if it is already in use by a driver! */
#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
#define I2C_SMBUS 0x0720 /* SMBus transfer */
/* This is the structure as used in the I2C_SMBUS ioctl call */
struct i2c_smbus_ioctl_data {
__u8 read_write;
__u8 command;
__u32 size;
union i2c_smbus_data __user *data;
};
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};
#define I2C_RDRW_IOCTL_MAX_MSGS 42
#ifdef __KERNEL__
#define I2C_MAJOR 89 /* Device major number */
#endif
#endif /* _LINUX_I2C_DEV_H */
5.Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := WakeUp
LOCAL_SRC_FILES := wakeup.cpp
LOCAL_LDLIBS += -L$(SYSTEM)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
6.生成.so文件(注意包名一直,否则不能够成功生成 libWakeUp.so文件)
7.直接调用
简单代码:
private int fd;
private int wakeUpState;
private int degree;
fd = WakeUp.open("", 0);
wakeUpState = WakeUp.getWakeUpState(fd);
degree = WakeUp.getWakeUpDegree();
提示还有一个命令问题:
chmod 777 /dev/i2c-0
chmod 777 /sys/class/gpio
chmod 777 /sys/class/gpio/export
echo 68 > /sys/class/gpio/export
chmod 777 /sys/class/gpio/gpio68
chmod 777 /sys/class/gpio/gpio68/direction
chmod 777 /sys/class/gpio/gpio68/edge
chmod 777 /sys/class/gpio/gpio68/value
setenforce 0
更新:上面的问题如何解决?参考链接:http://www.jianshu.com/p/5bda839f31ae