yyplc 发表于 2012-5-9 21:15

奇怪问题求助:linux视频子系统,为什么ioctl出错?

本帖最后由 yyplc 于 2012-5-10 17:33 编辑

今天写一个应用程序测试linux 视频子系统frame buffer设备,发现ioctl竟然出错,均返回-1,不知到为什么?
更奇怪的是,在内核端fb_ioctl加入printk调式,竟然也没有输出,说明用户程序ioctl的时候,根本不会执行fbioctl!!!
求助达人,指点一下linux菜鸟!
static const struct file_operations fb_fops = {
      .owner =      THIS_MODULE,
      .read =                fb_read,
      .write =      fb_write,
      .unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
      .compat_ioctl = fb_compat_ioctl,
#endif
      .mmap =                fb_mmap,
      .open =                fb_open,
      .release =      fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
      .get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
      .fsync =      fb_deferred_io_fsync,
#endif
};
用户程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
//#include <sys/types.h>
#include <fcntl.h>   
#include <linux/fb.h>
#include <sys/mman.h>

struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;

int main(void)
{
      int fd;
      int fbsize;
      unsigned char *fbbuf;
         char buf;
      int i,res,adc_data;

      if ((fd = open("/dev/fb0",O_RDWR)) < 0) {
            printf("open fb0 failed\n"undefined;
             return 1;
      }

          if((res = ioctl(fd,FBIOGET_FSCREENINFO,&finfo)) == -1)
            {
                printf("ERROR reading fixed information.error = %d\n",res);

      }

      if ((res = ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) ==-1) {
                printf("bad vscreeninfo ioctl.error = %d\n",res);
      }

      fbsize = vinfo.xres * vinfo.yres * (vinfo.bits_per_pixel/undefined;
      printf("fbisze: %d",fbsize);

      if ((fbbuf = mmap(0, fbsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*) -1)
      {
                printf("map video error.\n"undefined;
      }

      for (i = 0; i< fbsize; i++) {
                *(fbbuf+i) = 0x0;
      }
      munmap(fbbuf, fbsize);
      close(fd);

      return 0;
}

yyplc 发表于 2012-5-9 21:18

本帖最后由 yyplc 于 2012-5-9 21:23 编辑

其中:
static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{

struct inode *inode = file->f_path.dentry->d_inode;

int fbidx = iminor(inode);

struct fb_info *info = registered_fb;

printk("fb_ioctl....\n"); //这里加printk,但根本不会执行到这里!


return do_fb_ioctl(info, cmd, arg);
}

用户端调用流程应该是这样的:
用户ioctl() -->vfs_ioctl() -->fb_fops.unlocked_ioctl()
照理分析:fb_fops.unlocked_ioctl就是fb_ioctl的呀,但是printk调试跟踪,竟然没有进去
不知道跑哪了?

ycz9999 发表于 2012-5-9 22:13

前辈:
菜鸟有个问题想请教下您:
在学习字符设备的ioctl实现时记得ioctl的驱动实现函数原型是:
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

前辈的ioctl实现中只有3个参数,这样实现可行的吗?
我在自己的字符设备的ioctl实现中,去掉了那个struct inode *参数,结果编译出错了,还请前辈可以指点下~~~
:)

yyplc 发表于 2012-5-9 23:03

你用的ioctl是老式的,参数是有4个,用unlocked_ioctl就只有3个了。
你可以去看file_operations 结构体

ycz9999 发表于 2012-5-10 11:35

4# yyplc 嗯好的感谢前辈指点我再去看下那个结构体: )

yyplc 发表于 2012-5-10 17:34

解决了
犯了一个及其低级的错误!
楼主位的程序改正了
页: [1]
查看完整版本: 奇怪问题求助:linux视频子系统,为什么ioctl出错?