1.驱动.H结构体以及IOCTL接口定义
enum{
IOCTRL_READ_VALUE = 0x1001,
IOCTRL_WRITE_VALUE = 0x1002,
IOCTRL_READ_MSG = 0x1003,
IOCTRL_WRITE_MSG = 0x1004,
IOCTRL_READ_I2CMSG = 0x1005,
IOCTRL_WRITE_I2CMSG = 0x1006,
};
struct msg{
int en;
int addr;
unsigned char *data;
int len;
};
struct i2c_msg{
__u16 addr;
__u16 flags;
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
#define I2C_M_NOSTART 0x4000
__u16 len;
__u8 *buf;
}
2. 驱动.C 接口注册
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
static long xxx_ioctl(struct file *file, unsigned int cmd, unsigned long args)
{
int *val = (int *)args;
int value;
struct msg msg_data;
struct i2c_msg i2c_msg_data;
switch(cmd) {
case IOCTL_READ_VALUE:
value = 0xFF;
/*to do read data*/
if (copy_to_user((int __user *)arg, &value, sizeof(int)))
return -EFAULT;
break;
case IOCTL_WRITE_VALUE:
if (copy_from_user(&value, (int __user *)arg, sizeof(int)))
return -EFAULT;
printk("%s, IOCTL_WRITE_VALUE : %d\n",value);
/*to do write data.*/
break;
case IOCTL_READ_MSG:
if (copy_to_user((void __user *)arg, &msg_data, sizeof(msg)))
return -EFAULT;
break;
case IOCTL_WRITE_MSG:
if (copy_from_user(&msg_data, (void __user *)arg, sizeof(msg)))
return -EFAULT;
/*to do write msg.*/
break;
case IOCTL_READ_I2CMSG:
if (copy_to_user((void __user *)arg, &i2c_msg_data, sizeof(i2c_msg)))
return -EFAULT;
break;
case IOCTL_WRITE_I2CMSG:
if (copy_from_user(&i2c_msg_data, (void __user *)arg, sizeof(i2c_msg)))
return -EFAULT;
/*to do write msg.*/
break;
default:
printk(KERN_ERR "Unknown command required: %d\n", cmd);
return -EINVAL;
}
return ret;
}
/* xxx Misc driver interfaces */
static int xxx_open(struct inode *inode, struct file *file)
{
/*to to interface init.*/
return 0;
}
static int xxx_close(struct inode *inode, struct file *file)
{
/*to to interface release.*/
return 0;
}
/*dev设备文件操作*/
static const struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.open = xxx_open,
.release = xxx_close,
.unlocked_ioctl = xxx_ioctl,
};
static struct miscdevice xxx_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "xxx-ioctrl",
.fops = &xxx_fops,
};
static int __init xxx_modinit(void)
{
int ret = 0;
/*注册dev ioctrl设备节点*/
ret = misc_register(&xxx_misc);
if (ret < 0) {
printk(KERN_ERR "Failed to register XXX MISC driver: %d\n", ret);
}
}
static void __exit xxx_exit(void)
{
misc_deregister(&xxx_misc);
}
3. JNI接口
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
enum{
IOCTRL_READ_VALUE = 0x1001,
IOCTRL_WRITE_VALUE = 0x1002,
IOCTRL_READ_MSG = 0x1003,
IOCTRL_WRITE_MSG = 0x1004,
IOCTRL_READ_I2CMSG = 0x1005,
IOCTRL_WRITE_I2CMSG = 0x1006,
};
struct msg{
int en;
int addr;
unsigned char *data;
int len;
};
struct i2c_msg{
__u16 addr;
__u16 flags;
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
#define I2C_M_NOSTART 0x4000
__u16 len;
__u8 *buf;
}
/*Open打开dev接口*/
static int open_dev(void)
{
char fname[] = "/dev/xxx-ioctrl";
int fd = open(fname, O_RDWR);
return fd;
}
/*Close关闭dev ioControl接口*/
static void close_dev(int fd)
{
close(fd);
}
/*IOCTRL 传送结构体数据*/
static int do_writereg(int addr, int value)
{
int fd;
struct msg hd;
hd.en = 1;
hd.addr = addr;
hd.data = &value;
hd.len= 1;
fd = open_dev();
ioctl(fd, XXX_IOCTL_WRITEREG, &hd);
close_dev(fd);
return(0);
}
/*IOCTRL 传送int类型数据*/
static void do_sets(int nStatus)
{
int fd;
int status;
fd = open_dev();
ioctl(fd, IOCTRL_WRITE_VALUE , &nStatus);
close_dev(fd);
printf("XXX Get Status = %d\n", status);
}