Android IOCtrl使用[Driver + Jni]

1.驱动H结构体以及IOCTL接口定义

#define XXX_IOCTL_MAGIC's' #define XXX_MAGIC0xD0typedef struct _REG_CMD { unsigned char addr; unsigned char data; } REG_CMD; struct xxx_wreg_handle { REG_CMD *regcmd; int len; }; struct xxx_wcram_handle{ intdsp; intaddr; unsigned char *cram; intlen; }; #define XXX_IOCTL_SETSTATUS_IOW(XXX_MAGIC, 0x10, int) #define XXX_IOCTL_SETMIR_IOW(XXX_MAGIC, 0x12, int) #define XXX_IOCTL_GETMIR_IOR(XXX_MAGIC, 0x13, unsigned long) #define XXX_IOCTL_WRITEREG_IOW(XXX_MAGIC, 0x14, struct xxx_wreg_handle) #define XXX_IOCTL_WRITECRAM_IOW(XXX_MAGIC, 0x15, struct xxx_wcram_handle)

2. 驱动C接口注册
#include #include #include struct _xxx_pd_handler { int ref_count; struct mutex lock; struct xxx_priv *data; } xxx_pd_handler = { .ref_count = -1, .data = https://www.it610.com/article/NULL, }; static long xxx_ioctl(struct file *file, unsigned int cmd, unsigned long args) { struct xxx_priv *xxx = (struct xxx_priv*)file->private_data; struct xxx_wreg_handle xxx_wreg; struct xxx_wcram_handlexxx_wcram; void __user *data = https://www.it610.com/article/(void __user *)args; int *val = (int *)args; int i; unsigned long dwMIRData; int ret = 0; REG_CMDregcmd[MAX_WREG]; unsigned char cram_data[MAX_WCRAM]; switch(cmd) { case XXX_IOCTL_WRITECRAM: if (copy_from_user(&xxx_wcram, data, sizeof(struct xxx_wcram_handle))) return -EFAULT; if ( (xxx_wcram.len % 3 ) != 0 ) { printk(KERN_ERR"[xxx] %s CRAM len error\n",__FUNCTION__); return -EFAULT; } if ( ( xxx_wcram.len < 3 ) || ( xxx_wcram.len > MAX_WCRAM ) ) { printk(KERN_ERR "[xxx] %s CRAM len error2\n",__FUNCTION__); return -EFAULT; } for ( i = 0 ; i < xxx_wcram.len ; i ++ ) { cram_data[i] = xxx_wcram.cram[i]; } ret = xxx_write_cram(xxx->codec, xxx_wcram.dsp, xxx_wcram.addr, xxx_wcram.len, cram_data); break; case XXX_IOCTL_WRITEREG: if (copy_from_user(&xxx_wreg, data, sizeof(struct xxx_wreg_handle))) return -EFAULT; if ( ( xxx_wreg.len < 1 ) || ( xxx_wreg.len > MAX_WREG ) ) { printk(KERN_ERR "MAXREG ERROR %d\n", xxx_wreg.len ); return -EFAULT; } for ( i = 0 ; i < xxx_wreg.len; i ++ ) { regcmd[i].addr = xxx_wreg.regcmd[i].addr; regcmd[i].data = https://www.it610.com/article/xxx_wreg.regcmd[i].data; } xxx_reg_cmd(xxx->codec, regcmd, xxx_wreg.len); break; case XXX_IOCTL_SETSTATUS: ret = xxx_set_status(xxx->codec, val[0]); if (ret < 0) { printk(KERN_ERR "xxx: set_status error: \n"); return ret; } break; case XXX_IOCTL_SETMIR: xxx->MIRNo = val[0]; if (ret < 0) { printk(KERN_ERR "xxx: set MIR error\n"); return -EFAULT; } break; case XXX_IOCTL_GETMIR: XXX_readMIR(xxx->codec, (xxx->MIRNo/16), (0xF & (xxx->MIRNo)), &dwMIRData); ret = copy_to_user(data, (const void*)&dwMIRData, (unsigned long)4); if (ret < 0) { printk(KERN_ERR "xxx: get status error\n"); return -EFAULT; } break; break; default: printk(KERN_ERR "Unknown command required: %d\n", cmd); return -EINVAL; }return ret; }static int init_xxx_pd(struct xxx_priv *data) { struct _xxx_pd_handler *xxx = &xxx_pd_handler; if (data =https://www.it610.com/article/= NULL) return -EFAULT; mutex_init(&xxx->lock); mutex_lock(&xxx->lock); xxx->data = https://www.it610.com/article/data; mutex_unlock(&xxx->lock); printk("data:%p, xxx->data:%p\n", data, xxx->data); return 0; }static struct xxx_priv* get_xxx_pd(void) { struct _xxx_pd_handler *xxx = &xxx_pd_handler; if (xxx->data =https://www.it610.com/article/= NULL) return NULL; mutex_lock(&xxx->lock); xxx->ref_count++; mutex_unlock(&xxx->lock); return xxx->data; }static int rel_xxx_pd(struct xxx_priv *data) { struct _xxx_pd_handler *xxx = &xxx_pd_handler; if (xxx->data =https://www.it610.com/article/= NULL) return -EFAULT; mutex_lock(&xxx->lock); xxx->ref_count--; mutex_unlock(&xxx->lock); data = https://www.it610.com/article/NULL; return 0; }/* xxx Misc driver interfaces */ static int xxx_open(struct inode *inode, struct file *file) { struct xxx_priv *xxx; xxx = get_xxx_pd(); file->private_data = https://www.it610.com/article/xxx; return 0; }static int xxx_close(struct inode *inode, struct file *file) { struct xxx_priv *xxx = (struct xxx_priv*)file->private_data; rel_xxx_pd(xxx); 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); }

【Android IOCtrl使用[Driver + Jni]】3. JNI API接口.
#include #include #include #include #include #include #define XXX_IOCTL_MAGIC's' #define XXX_MAGIC0xD0typedef struct _REG_CMD { unsigned char addr; unsigned char data; } REG_CMD; struct xxx_wreg_handle { REG_CMD *regcmd; int len; }; struct xxx_wcram_handle{ intdsp; intaddr; unsigned char *cram; intlen; }; #define XXX_IOCTL_SETSTATUS_IOW(XXX_MAGIC, 0x10, int) #define XXX_IOCTL_SETMIR_IOW(XXX_MAGIC, 0x12, int) #define XXX_IOCTL_GETMIR_IOR(XXX_MAGIC, 0x13, unsigned long) #define XXX_IOCTL_WRITEREG_IOW(XXX_MAGIC, 0x14, struct xxx_wreg_handle) #define XXX_IOCTL_WRITECRAM_IOW(XXX_MAGIC, 0x15, struct xxx_wcram_handle)/*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 xxx_wreg_handle hd; hd.len = 1; regcmd[0].addr = addr; regcmd[0].data = https://www.it610.com/article/value; hd.regcmd = regcmd; 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, XXX_IOCTL_SETSTATUS, &nStatus); close_dev(fd); printf("XXX Get Status = %d\n", status); }


    推荐阅读