免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2956 | 回复: 9
打印 上一主题 下一主题

应用程序通过iotcl往驱动传参数,居然收到是错的。。。。。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-04 17:30 |只看该作者 |倒序浏览
本帖最后由 zheguzai 于 2012-05-04 17:46 编辑

今天遇到这个问题,简直让我很吐血,搞了好久还是不行,因为感觉这个根本就不会出问题的,可是居然出了这种问题
以前的驱动要添加接口,所以我就在原来驱动的ioctl中添加了一项,并且通过应用程序调用该ioctl,可是奇怪的事情发生了,我传递给
驱动的数据,居然不是我想要的,搞了半天都不行,期间试了两种方法,第一种:驱动中不用copy_from_user()函数来接收从应用传来的指针,可是这样也不行,第二种,就是用copy_from_user()函数来接受从应用传来的指针,可是还是不行。不说了上代码,大家帮我看看,哪里出问题了。。。。

应用层代码,调用的代码很简单就两句。。。。我从应用传过去的数据就是1和2,其他的数据都会报错的。

  1.         int channel= 2;
  2.         if (ioctl(inputFd, VPFE_CMD_SELECT_TVP5158_CHANNEL, &channel) == -1)
  3.                         {
  4.                                 printf("VPFE_CMD_SELECT_TVP5158_CHANNEL failed\n");
  5.                         }
复制代码
驱动代码:
  1. case VPFE_CMD_SELECT_TVP5158_CHANNEL:
  2.         {   
  3.    
  4.             int  channel_id;

  5.             copy_from_user(&channel_id, (int *)arg, sizeof(int));
  6.            
  7.             printk("channel_id = %d\n",channel_id);//本来这句打印出来应该是2的,可是它不是,是个垃圾数值,

  8.             if (channel_id < 1 || channel_id > 2)
  9.             {   
  10.                 ret = -EINVAL;
  11.                 break;
  12.             }   

  13.             tvp5158_ctrl(TVP5158_SELECT_CHANNEL, &channel_id);
  14.             break;
  15.         }   

复制代码
驱动中刚开始用这种方式实现的。一样是不行的
  1. case VPFE_CMD_SELECT_TVP5158_CHANNEL:
  2.         {   
  3.    
  4.             int  *channel_id = (int *)arg;
  5.            
  6.             printk("channel_id = %d\n",*channel_id);//本来这句打印出来应该是2的,可是它不是,是个垃圾数值,

  7.             if (*channel_id < 1 || *channel_id > 2)
  8.             {   
  9.                 ret = -EINVAL;
  10.                 break;
  11.             }   

  12.             tvp5158_ctrl(TVP5158_SELECT_CHANNEL, channel_id);
  13.             break;
  14.         }   
复制代码
大家帮我看看,看是哪里出错了,谢谢了 。。。。。。。。。。

论坛徽章:
0
2 [报告]
发表于 2012-05-04 18:03 |只看该作者
本帖最后由 xxw19840406 于 2012-05-04 18:04 编辑

void __user *arg = (void __user *)arg;
驱动中arg有没有这个

然后copy_from_user(&channel_id, (int *)arg, sizeof(int));
改成 copy_from_user(&channel_id, arg, sizeof(int));

代码贴全点

论坛徽章:
0
3 [报告]
发表于 2012-05-04 19:35 |只看该作者
xxw19840406 发表于 2012-05-04 18:03
void __user *arg = (void __user *)arg;
驱动中arg有没有这个



驱动里面没有你说的  void __user *arg = (void __user *)arg; 这句的。

论坛徽章:
0
4 [报告]
发表于 2012-05-04 20:58 |只看该作者
不应该用copy_from_user的:wink:

论坛徽章:
0
5 [报告]
发表于 2012-05-07 09:40 |只看该作者
zheguzai 发表于 2012-05-04 19:35
驱动里面没有你说的  void __user *arg = (void __user *)arg; 这句的。

这个不一定是真正的原因
一般copy_from_user都是要检查返回的,LZ可以看看是否出错

论坛徽章:
0
6 [报告]
发表于 2012-05-07 10:09 |只看该作者
xxw19840406 发表于 2012-05-07 09:40
这个不一定是真正的原因
一般copy_from_user都是要检查返回的,LZ可以看看是否出错




查过了,返回值就是错误的。。。。

论坛徽章:
0
7 [报告]
发表于 2012-05-12 10:40 |只看该作者
ldd3 中的做法是:因为ioctl 通常涉及到小的数据,所以先用access_ok()验证用户空间地址有效性,
然后使用不做类型检查的快速的函数:  put_user(), __put_user(), get_user,__get_user().

你把代码改成这样试试。
  1. case VPFE_CMD_SELECT_TVP5158_CHANNEL:
  2.         {   
  3.    
  4.             int  channel_id;

  5.             int err = access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
  6.             if(!err)    return -EFAULT;
  7.             __get_user(channel_id, (int __user *)arg);
  8.            
  9.             printk("channel_id = %d\n",channel_id);//本来这句打印出来应该是2的,可是它不是,是个垃圾数值,

  10.             if (channel_id < 1 || channel_id > 2)
  11.             {   
  12.                 ret = -EINVAL;
  13.                 break;
  14.             }   

  15.             tvp5158_ctrl(TVP5158_SELECT_CHANNEL, &channel_id);
  16.             break;
  17.         }   
复制代码

论坛徽章:
0
8 [报告]
发表于 2012-05-23 14:19 |只看该作者
友情提醒:你检查一下你的ioctl的原型和你的ioctl函数的实现,看看两者的参数个数是不是一致。

论坛徽章:
0
9 [报告]
发表于 2012-05-23 21:07 |只看该作者
做个记号,下次好找!

论坛徽章:
0
10 [报告]
发表于 2012-06-05 16:12 |只看该作者
非常感谢大家的回帖,那个davinci VPFE驱动里对IOCTL又进行了一次封装,本来我们只写一个ioctl函数的,它又写了一个调用真正的ioctl,并且对参数进行了处理。。。所以我的那个参数传进去之后就不对了。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP