• tiny4412--linux驱动学习(1)


    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 *);
        …………
    }

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

  • 相关阅读:
    功能点方法
    学数答题160908-数论不等式
    学数答题160903-函数方程
    学数答题160906-不等式最值
    学数答题160905-函数方程
    学数答题160904-不等式
    学数答题160903-三角函数
    kitti-b站教程
    kitti数据集介绍
    SLAM:理论与实践
  • 原文地址:https://www.cnblogs.com/chu-yi/p/10539700.html
Copyright © 2020-2023  润新知