字符设备框架(ioctrl)

来源:互联网 发布:淘宝卖家视频教程 编辑:程序博客网 时间:2024/06/07 16:14

1、driver

#include <linux/kernel.h>#include <linux/init.h>#include <linux/types.h>#include <linux/spinlock.h>#include <linux/blkdev.h>#include <linux/module.h>  #include <linux/fs.h>  #include <linux/errno.h>  #include <linux/mm.h>  #include <linux/cdev.h>  //module_param(mem_major, int, S_IRUGO);  #define MEMDEV_MAJOR        260     /*预设的mem的主设备号*/  #define MEMDEV_NR_DEVS      2       /*设备数*/  #define MEMDEV_SIZE         4096  #define CHAR_DEV_NAME       "memdev"  static int mem_major = 0; //MEMDEV_MAJOR;  struct class *pclass = NULL;    struct cdev my_dev;     int mem_open(struct inode *inode, struct file *filp)  {      return 0;   }    int mem_release(struct inode *inode, struct file *filp)  {      return 0;  }  /*'k'为幻数,要按照Linux内核的约定方法为驱动程序选择ioctl编号,应该首先看看include/asm/ioctl.h和Documentation/ioctl-number.txt这两个文件.对幻数的编号千万不能重复定义,如ioctl-number.txt已经说明‘k'的编号已经被占用的范围为:'k'    00-0F    linux/spi/spidev.h    conflict!'k'    00-05    video/kyro.h        conflict!所以我们在这里分别编号为0x1a和0x1b*/#define CMD_MAGIC   'k'#define MEM_CMD1    _IO(CMD_MAGIC, 0x1a)#define MEM_CMD2    _IO(CMD_MAGIC, 0x1b)int temp_data = 0;static int mem_ioctl( struct file *file, unsigned int cmd, unsigned long arg){        switch(cmd)    {        case MEM_CMD1:            if(copy_from_user(&temp_data,  (int *)arg, sizeof(int)))                 return -EFAULT;            break;                case MEM_CMD2:            if(copy_to_user( (int *)arg, &temp_data, sizeof(int)))                 return -EFAULT;            break;    }        //printk(KERN_NOTICE"ioctl CMD%d done!\n",temp);        return 0;}static const struct file_operations mem_fops =  {      .owner = THIS_MODULE,      .unlocked_ioctl = mem_ioctl,    .open = mem_open,      .release = mem_release,  };  static int memdev_init(void)  {      int result;      int i;      dev_t devno = MKDEV(mem_major, 0);      if (mem_major) { /* 静态申请设备号*/          result = register_chrdev_region(devno, 2, CHAR_DEV_NAME);      } else { /* 动态分配设备号 */          result = alloc_chrdev_region(&devno, 0, 2, CHAR_DEV_NAME);          mem_major = MAJOR(devno);      }       if (result < 0)          return result;      cdev_init(&my_dev, &mem_fops);      my_dev.owner = THIS_MODULE;      my_dev.ops = &mem_fops;      cdev_add(&my_dev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);      pclass = class_create(THIS_MODULE, CHAR_DEV_NAME);      if (IS_ERR(pclass))      {          printk("class_create failed!/n");          goto failed;      }      device_create(pclass, NULL, devno, NULL, CHAR_DEV_NAME);      return 0;  failed:       cdev_del(&my_dev);    unregister_chrdev_region(devno, 1);      return result;  }    static void memdev_exit(void)  {      device_destroy(pclass, MKDEV(mem_major, 0));      class_destroy(pclass);        cdev_del(&my_dev);    unregister_chrdev_region(MKDEV(mem_major, 0), 2); }    MODULE_AUTHOR("derek yi");  MODULE_LICENSE("GPL");    module_init(memdev_init);  module_exit(memdev_exit);  

2, app

#include <stdio.h>  #include <fcntl.h>  #include <stdlib.h>  #include <string.h>  #include <sys/types.h>  #include <sys/stat.h>#include <unistd.h>#include <sys/ioctl.h>#define CMD_MAGIC   'k'#define MEM_CMD1    _IO(CMD_MAGIC, 0x1a) // write#define MEM_CMD2    _IO(CMD_MAGIC, 0x1b) // readint main(){    int fd;    int ret;    int wdata, rdata;    fd = open("/dev/memdev", O_RDWR);    if( fd < 0 ) {        printf("open memdev WRONG!\n");        return 0;    }    ret = ioctl(fd, MEM_CMD2, &rdata);    printf("ioctl: ret=%d rdata=%d\n", ret, rdata);    wdata = 42;    ret = ioctl(fd, MEM_CMD1, &wdata);    ret = ioctl(fd, MEM_CMD2, &rdata);    printf("ioctl: ret=%d rdata=%d\n", ret, rdata);        close(fd);    return 0;}






0 0