Linux驱动Day02

一、设备的分类

1、设备可以分为:字符设备、块设备、网络设备

字符设备:以字节流的形式进行数据读写。
块设备:存储设备。
网络设备:网卡。

2、描述字符设备的结构体cdev

<linux/cdev.h>  
   struct cdev {
   	struct module *owner;   //THIS_MODULE
  	struct file_operations *ops; //操作方法集
   	dev_t dev;      //设备号
  	unsigned int count;    //设备计数 
  };

3、操作方法集

struct file_operations {
   struct module *owner;   
   loff_t (*llseek) (struct file *, loff_t, int);   
   /* read 接口 */
   ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
   /* write 接口 */
   ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
   /* poll接口 */
   unsigned int (*poll) (struct file *, struct poll_table_struct *);
   /* ioctl接口 */
   long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
   /* open 接口 */
   int (*open) (struct inode *, struct file *);
   /* release 接口*/
   int (*release) (struct inode *, struct file *);
   /* 异步通知接口 */
   int (*fasync) (int, struct file *, int);
  };

4、设备号

dev_t dev;  __u32 
  
  主设备和次设备号组成
  
  主设备号:高12bit
  
  MAJOR(dev_t dev)
  
  #define MINORBITS 20
  #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
  
  MINOR(dev_t dev) //次设备号
  
  #define MINORMASK ((1U << MINORBITS) - 1)
  #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
  
  MKDEV(int major,int minor)

二、字符设备驱动编写

1、申请设备号
自动分配设备号

/****************************************************************************
    *参数: 
    *   @dev   dev_t类型的指针
    *   @baseminor  次设备号的起始
    *   @count   设备个数
    *   @name   设备名
    *返回值:成功返回0,失败返回负数错误码
    ***************************************************************************/  
    int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

手动指定设备号

/****************************************************************************
    *参数: 
    *   @from  设备号   MKDEV(int major , int minor)
    *   @count  设备个数
    *   @name  设备名
    *返回值:成功返回0,失败返回负数错误码
    ***************************************************************************/ 
int register_chrdev_region(dev_t from, unsigned count, const char *name)
void unregister_chrdev_region(dev_t from, unsigned count)

2、分配cdev结构体

/***************************************
     *参数:
  *  @void
  *返回值:成功返回cdev结构体指针,失败
  *   返回NULL
     **************************************/
  struct cdev *cdev_alloc(void)

3、初始化cdev结构体

/**********************************************************************
   *参数: 
   *  @cdev cdev结构体指针
   *  @fops   操作方法集指针
   *返回值:void
   *********************************************************************/
   void cdev_init(struct cdev *cdev, const struct file_operations *fops)

4、将cdev添加到内核中

/***************************************************************
   *参数: 
   *   @p    cdev结构指针
   *   @dev 设备号
   *   @count 设备个数
   *返回值:成功返回0,失败返回负数错误码
   **************************************************************/
   int cdev_add(struct cdev *p, dev_t dev, unsigned count)
   void cdev_del(struct cdev *p)
   

三、字符设备驱动文件创建

1、 通过命令创建设备文件

mknod - make block or character special files

mknod NAME TYPE [MAJOR MINOR]

TYPE : c 字符设备 b :块设备
NAME : 设备文件名

2、通过udev守护进程创建

class_create

device_crete

猜你喜欢

转载自blog.csdn.net/weixin_43008143/article/details/107994507