1,概述

linux设备驱动分为三种:字符驱动设备、块驱动设备、网络设备

架构:

1,字符设备驱动

  是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。

2.块设备驱动

  是指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等。

3网络设备驱动

  网卡驱动,CAN驱动等

 

2,驱动的静态加载和动态加载

区别:

1,编译选择不一样。选择 * 就是编入内核镜像 ,选择 M 是单独编为一个驱动模块,独立存在于文件系统上;

2,静态加载,在内核中加载时间靠前;动态加载,在文件系统中为 .ko的文件,需要等到系统跑起来之后,手动用insmod 命令加载,时间相对靠后 。

 

动态加载的优势:

1,支持热插拔

2,有利于驱动调试

3,开机优化。界面启动快

 

——————————————————————————————————————————————————————————————————————————

字符设备驱动:

 

1,概念

(1)设备号

    内核中通过类型 dev_t 来描述设备号,其实质是 unsigned int 32位整数,其中高12位为主设备号(用来区分不同类别的设备),低20位为次设备号(用来区分同一类别的不同设备)

    注册函数:

      1. 静态申请:

        int register_chrdev_region (dev_t from, unsigned count,  const char *name)

 

/**
 * register_chrdev_region() - register a range of device numbers
 * @from: the first in the desired range of device numbers; must include
 *        the major number.
 * @count: the number of consecutive device numbers required
 * @name: the name of the device or driver.
 *
 * Return value is zero on success, a negative error code on failure.
 */

 

      2.动态分配:  

        int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);  

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
     /**
 * alloc_chrdev_region() - register a range of char device numbers
 * @dev: output parameter for first assigned number
 * @baseminor: first of the requested range of minor numbers
 * @count: the number of minor numbers required
 * @name: the name of the associated device or driver
 *
 * Allocates a range of char device numbers.  The major number will be
 * chosen dynamically, and returned (along with the first minor number)
 * in @dev.  Returns zero or a negative error code.
 */

        3.注销设备号:

        void unregister_chrdev_region(dev_t from, unsigned count);

 

           获取设备号 :

#define MINORBITS    20
#define MINORMASK    ((1U << MINORBITS) - 1)
#define MAJOR(dev)    ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev)    ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))

 

(2)设备信息的描述

    

struct cdev {
    struct kebject kobj;                //由内核中设备管理模型来操作
    struct module  *owner;               //为了加载驱动实现的,都会给它赋值  
    const  struct  file_operations  *ops;      //函数集
    struct  list_head  list;              //链表
    dev_t  dev;                      //设备号
    unsignde int count;                 //支持的设备
};

 

(3)设备行为的描述

 

/include/linux/fs.h

struct file_openrations {
    struct module  *owner;
    …………
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
    ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
    …………
}

 

从下一节开始,我们手动编写一个字符驱动。

posted on 2019-04-08 17:23  ._初一  阅读(234)  评论(0编辑  收藏  举报