首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

ioctl的疑问解决办法

2012-02-21 
ioctl的疑问驱动部分:C/C++ codeMODULE_LICENSE(GPL)#define TEST_ENA0x00#define TEST_SET_TIME0x01#d

ioctl的疑问
驱动部分:

C/C++ code
MODULE_LICENSE("GPL");#define TEST_ENA                  0x00#define TEST_SET_TIME             0x01#define TEST_SET_DATE             0x02 #define TEST_SET_CH0_PIXEL        0x03 int test_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){    unsigned int __user *argp=(unsigned int __user *)arg;    unsigned char tmp_uchar;    printk("CMD=%d",cmd);    switch (cmd)    {        case TEST_ENA                :          break;                                     case TEST_SET_TIME           :                     break;        case TEST_SET_DATE:         break;        case TEST_SET_CH0_PIXEL      :          break;        default:        break;    }//end switch    return 0;    }

测试程序:
C/C++ code
int main(void){          int wdt_fd = -1;        int ret,nTimeout=20;        int i;        Osd_Date osd_date;        wdt_fd = open("/dev/ti_test",O_WRONLY);        if(wdt_fd == -1)        {            printf("CEM  Open  error!!\n");        }                        i=2;        ret=ioctl(wdt_fd, i ,&nTimeout);        printf("ret=%d \n",ret);    return 0;}

结果发现ioctl在i=2的时候,不会调用test_ioctl,其他时候均没有问题,返回值是0,希望高手指点下
网上搜索了下,有人说
引用第二个参数不要用2。可以用linux/ioctl.h里面提供的IOC宏

2好像被2.6的内核干掉了。以前我喜欢直接用0x01, 0x02,后来全改成IOW/IOR了



[解决办法]
在别人地盘混 怎么能不守规矩
老实从了__IOW _IOR 吧

[解决办法]
ioctl的cmd不是想怎么定义就怎么定义的 得按规矩来
内核有一个自定义头文件 用户层也得有一个相同的自定义头文件
每一个头文件都必须使用__IOW _IOR来定义这些cmd

如果你随便定义一个cmd 很可能就跟linux内核中这类驱动已经定义好的cmd重复
于是就优先被这类驱动默认的ioctl处理函数截获了,只有这类驱动默认的ioctl处理函数不认识的cmd,才轮得到你自定义的ioctl
[解决办法]
听说比较新的版本ioctl接口发生了变化了,不过好久没搞驱动了,忘了。
[解决办法]
不知道你的版本
以3.0.4为例
fs/ioctl.c 
(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) -> do_vfs_ioctl

C/C++ code
int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,         unsigned long arg){    int error = 0;    int __user *argp = (int __user *)arg;    struct inode *inode = filp->f_path.dentry->d_inode;    switch (cmd) {    case FIOCLEX:        set_close_on_exec(fd, 1);        break;    case FIONCLEX:        set_close_on_exec(fd, 0);        break;    case FIONBIO:        error = ioctl_fionbio(filp, argp);        break;    case FIOASYNC:        error = ioctl_fioasync(fd, filp, argp);        break;    case FIOQSIZE:        if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||            S_ISLNK(inode->i_mode)) {            loff_t res = inode_get_bytes(inode);            error = copy_to_user(argp, &res, sizeof(res)) ?                    -EFAULT : 0;        } else            error = -ENOTTY;        break;    case FIFREEZE:        error = ioctl_fsfreeze(filp);        break;    case FITHAW:        error = ioctl_fsthaw(filp);        break;    case FS_IOC_FIEMAP:        return ioctl_fiemap(filp, arg);    [b]case FIGETBSZ:[/b]        return put_user(inode->i_sb->s_blocksize, argp);    [b]default:[/b]        if (S_ISREG(inode->i_mode))            error = file_ioctl(filp, cmd, arg);        else            error =[b] vfs_ioctl[/b](filp, cmd, arg);        break;    }    return error;} 

热点排行