1,驱动代码中注册ioctl设备
1)在驱动代码中初始化结构体miscdevice,如下:
static struct miscdevice demo_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "demo_misc_dev",
.fops = &demo_misc_fops,
};
2)在probe函数中注册misc设备,如下:
ret = misc_register(&demo_misc_device);
if (ret) {
printk("\ndemo_misc_device register failed\n");
}
3)初始化demo_misc_device结构体中的fops函数接口,如下:
static const struct file_operations demo_misc_fops = {
.owner = THIS_MODULE,
.open = demo_misc_open,
.release = demo_misc_release,
.unlocked_ioctl = demo_misc_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = demo_misc_ioctl,
#endif
};
4)实现demo_misc_fops中的函数定义。如下:
static int demo_misc_open(struct inode *inode, struct file *filp)
{
int ret = 0;
if (g_data == NULL)
return -1;
filp->private_data = (void*)g_data;
ret = nonseekable_open(inode, filp);
return ret;
}
static int demo_misc_release(struct inode *inode, struct file *filp)
{
filp->private_data = NULL;
return 0;
}
static long demo_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int retval = 0;
int status = 0;
struct demo_device_info *pf_data;
void __user *argp = (void __user *) arg;
pf_data = (struct demo_device_info*)filp->private_data;
switch (cmd) {
case DEMO_IOCTL_GET_STATUS:
status =1;
if (copy_to_user(argp, &status, sizeof(status))) {
retval = -1;
}
break;
default:
retval = -1;
break;
}
return retval;
}
5)头文件中定义ioctl所实现的命令,如下:
#define DEMO_IOCTL 'z'
#define DEMO_IOCTL_GET_STATUS _IOR(DEMO_IOCTL, 0x01, int)
2,jni的C代码中调用ioctl接口,如下:
首先,内核驱动中关于DEMO_IOCTL_GET_STATUS的定义也要拷过来。
另外,定义jni的接口函数,如下:
JNIEXPORT void JNICALL Java_com_serialporttest_api_sample_SerialPortTest_demoioctl
(JNIEnv *env, jobject thiz,jint ctlcmd)
{
int fd;
int status;
int ret;
fd = open("/dev/demo_misc_dev",O_RDWR);
switch(ctlcmd){
case 1:
ret = ioctl(fd, DEMO_IOCTL_GET_STATUS,&status);
break;
default:
break;
}
}
3,android应用层调用jni中的函数接口
1)声明jni函数,如下:
public native static void demoioctl(int ctlcmd);
2)调用jni函数,如下:
demoioctl(1);