Android - IOCTL用法返回ENOTTY

时间:2013-08-21 11:06:55

标签: android module kernel ioctl

我正在尝试在Android上运行一个简单的IOCTL示例。我正在使用内核2.6和ICS。模块已正确注册/取消注册(insmod / rmmod)。但是,每次尝试在模拟器上执行./user_app时,我总是得到

error: first ioctl: Not a typewriter 
error: second ioctl: Not a typewriter 
message: `�

这显然是一个ENOTTY。我调试了应用程序,没有执行fops过程(device_ioctl,read_ioctl和write_ioctl)。

我想知道在Android上使用/实现IOCTL是否有任何限制。非常感谢你提前。

- 劳尔

以下是代码:

的module.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

#define MY_MACIG 'G'
#define READ_IOCTL _IOR(MY_MACIG, 0, int)
#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)


int main(){
    char buf[200];
    int fd = -1;
    if ((fd = open("/data/local/afile.txt", O_RDWR)) < 0) {
        perror("open");
        return -1;
    }
    if(ioctl(fd, WRITE_IOCTL, "hello world") < 0)
        perror("first ioctl");
    if(ioctl(fd, READ_IOCTL, buf) < 0)
        perror("second ioctl");

    printf("message: %s\n", buf);
    return 0;

}

user_app.c

#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#define MY_MACIG 'G'
#define READ_IOCTL _IOR(MY_MACIG, 0, int)
#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)

static char msg[200];

static ssize_t device_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset)
{
    ...
}


static ssize_t device_write(struct file *filp, const char __user *buff, size_t len, loff_t *off)
{
    ...
}
char buf[200];
int device_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) {
    int len = 200;
    switch(cmd) {
    case READ_IOCTL:    
        ...
        break;

    case WRITE_IOCTL:
        ...
        break;

    default:
        return -ENOTTY;
    }
    return len;

}
static struct file_operations fops = {
    .read = device_read, 
    .write = device_write,
    .unlocked_ioctl = device_ioctl,
};

static int __init example_module_init(void)
{
    printk("registering module");
    return 0;
}

static void __exit example_module_exit(void)
{
    printk("unregistering module");
}  

module_init(example_module_init);
module_exit(example_module_exit);
MODULE_LICENSE("GPL");

1 个答案:

答案 0 :(得分:0)

这是您发布的整个代码吗?初始化模块时不注册char设备,因此无法使用。
另外,在分配IOCTLS号码时要小心。在错误的文件上使用保留的IOCTL时,您将获得ENOTTY。请咨询this以确保您没有冲突。
阅读有关char驱动程序here的更多信息。