Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177022
  • 博文数量: 69
  • 博客积分: 2627
  • 博客等级: 少校
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-24 22:37
文章分类

全部博文(69)

文章存档

2017年(3)

2014年(1)

2013年(4)

2012年(6)

2011年(21)

2010年(15)

2009年(19)

我的朋友

分类: LINUX

2010-01-04 14:32:59

1.用户空间的ioctl:
  int ioctl(int fd,int cmd,...);  /* ... 表示一个可选的参数,而不是一个可变参数 */

2.驱动程序空间的ioctl:
  int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);

3.注册ioctl:

struct file_operations f_ops={
  read: ..,
  write: ..,
  ...
  ioctl:scull_ioctl,
};

4.ioctl的命令号要唯一,用四个宏来生成命令号:
  type :一个magic数,比如'k'
  nr   :  序号,0,1,2,...
  size :数据项的长度
 
  _IO(type,nr);
  _IOR(type,nr,size);
  _IOW(type,nr,size);
  _IORW(type,nr,size);

5.scull_ioctl:

int scull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){
  switch(cmd){
    case SCULL_XXX:  /* #define SCULL_XXX _IO('k',0)  ,#define SCULL_XXX _IOR('k',0,0) and so on */
       ...
       break;
    case SCULL_YYY:
       ...
       break;
    ...
  }
  return 0;
}




scull.c
-----------------------
#include
#include
#include
#include
#include "scull.h"

MODULE_LICENSE("GPL");

int scull_open(struct inode *inode,struct file *filp);
int scull_release(struct inode *inode,struct file *filp);
int scull_read(struct file *filp,char *buf,size_t count,loff_t *f_pos);
int scull_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos);
int scull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);

struct file_operations scull_fops={
    read:    scull_read,
    write:   scull_write,
    open:    scull_open,
    release: scull_release,
    ioctl:   scull_ioctl,
};


int init_module(void){
    int result;
  
    printk("<1> scull initilized.\n");

    result=register_chrdev(scull_major,"scull",&scull_fops);
    if(result<0){
        printk("<1> scull: can't get major %d\n",scull_major);
        return result;
    }

    if(scull_major==0) scull_major=result;
    printk("<1> major=%d\n",scull_major);
    return 0;
}

void cleanup_module(void){
  int result;
  printk("<1> when unload,major=%d\n",scull_major);
    result=unregister_chrdev(scull_major,"scull");
    if(result==-EINVAL)
      printk("<1> cleanup failed.");
    else
      printk("<1> scull removed.\n");
}


int scull_open(struct inode *inode,struct file *filp){
    printk("<1> scull opened.\n");
    MOD_INC_USE_COUNT;
    printk("<1> jiffies in open is : %ld",jiffies);
    return 0;
}

int scull_release(struct inode *inode,struct file *filp){
    printk("<1> scull closed.\n");
    MOD_DEC_USE_COUNT;
    return 0;
}

int scull_read(struct file *filp,char *buf,size_t count,loff_t *f_pos){
    printk("<1> scull be called 'read'.\n");
    printk("<1> jiffies in read is :%ld",jiffies);
    return 0;
}

int scull_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos){
    printk("<1> scull be called 'write'.\n");
    return 0;
}

int scull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){
  switch(cmd){
  case SCULL_IOCTL1:
    printk("you called scull_ioctl1 method.\n");
    break;
  case SCULL_IOCTL2:
    printk("you called scull_ioctl2 method.\n");
    break;
  }
  return 0;

}




test_scull.c
-----------------------
#include
#include
#include
#include
#include
#include "scull.h"

int main(){
  int fd;
  char buf[128];

  fd=open("/dev/scull",O_RDWR);
  read(fd,buf,1);
  write(fd,buf,1);
  ioctl(fd,SCULL_IOCTL1);
  ioctl(fd,SCULL_IOCTL2);
  close(fd);
  return 0;
}
 
 
阅读(1066) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~