七。内核字符驱动

来源:互联网 发布:金昌印花软件 编辑:程序博客网 时间:2024/06/10 06:24
如有什么错误大家要告诉我,一起学习:

#########################################
# 在内核函数中,尽量不要定义太大的局部变量
# 内核为每个进程在内核中分配一个 2页的内核栈(咱们这就是8K)
# 如果变量太大,会把栈的东西填满,栈里面放着进程很重要的东西, struct task_info 在这里面包含 struct task_struct
# 可以使用 malloc,分配的内粗是在堆里,不影响栈的
###########################################

1、设备类型:
    字符设备:能够按照字节流有序的访问的设备
        不能 seek,能seek就不是有序的访问了
    块设备:只能按照规定的块大小取访问的设备
    网络设备:通过网络协议栈访问的设备;
        网络设备不对应文件,在 /dev 下不对应节点

    选择:
        大多数是字符设备;SD卡、硬盘、nand 等是块设备;网卡是网络设备

    设备驱动:
        向下操作硬件,向上给user提供接口

2、字符设备:led设备、wdt设备(消费电子中看门狗驱动一般用不到,工控领域中一般会用到[打开,关闭,定时])、pwm(timer)设备,在 /dev 下挂载文件,打开关闭操作文件进行相应的操作
    /dev/led
        open /dev/led
        write 123 ---> /dev/led        on 点灯
        write 456 ---> /dev/led        off 关灯

    字符设备的核心头文件 < linux/cdev.h >

    设备号:
        每一个设备都会有一个设备号,是唯一的
        主设备号:表示一类设备
        次设备号:表示一类设备中的某个设备
            主设备号找驱动,次设备号找设备

    用户态创建设备节点:
        mknod led  c 10 20
        mknod led1 c 10 20
        mknod led2 c 10 20

    每一个字符设备都会对应一个结构体 struct cdev,向添加就必须自己添加这么一个结构体
        此结构体对应一个或多个结构体:
        struct cdev {
            struct kobject kobj;    //设备模型核心,与C++里的基类相似,用于组织设备;内核操作,
             struct module *owner;    //一般不用初始化,初始化写成 THIS_MODULE 就行
            const struct file_operations *ops;    
                //该设备的操作集 open release write read ioctl(万能的io操作,看怎么配置)
                硬件相关的操作都在此操作集中
            struct list_head list;    
            dev_t dev;    //该设备的设备号,主设备号、次设备号都在这一个变量里
                主次设备号在哪一位不需记,更改内核版本可能会变
                    获得主设备号:MAJOR(dev)
                    获得次设备号:MINOR(dev)
            unsigned int count;        //对应的设备节点个数;可多个设备节点对应一个结构体
                第一个设备号是 10 20, count 是节点是,第二个设备号是 10 21, 根据count的个数一次加;主设备号不变
        };

    创建一个设备号        MKDEV(major, minor) 参数自己填,到此处不能保证设备号不重复
    保证不重复的方法:(上面申请完了要告诉内核,使用下面的方法)
        存放全部设备的设备号 cat /proc/device, 可查阅哪个设备号没用
        自己规定设备号:(需要先查看哪个设备号不用,否则会出错)
            register_chrdev_region()        注册设备号
            unregister_chrdev_region()        注销设备号

        内核给分配设备:(内核动态分配,就不需要MKDEV申请了)
            alloc_chrdev_region()        分配一个设备号
            unregister_chrdev_region()    注销一个设备号

    申请设备步骤:(注意与设备号的区别,这是设备)
        struct chev led_dev = {xxx};
        cdev_init    初始化字符设备
        cdev_add    把字符设备注册到内核
        cdev_del    把字符设备从内核中注销

3、代码参考 <path>/05cdev/01dummy
    字符设备驱动05cdev/01dummy中测试方法:
    
    在当前目录下创建一个节点       mknod mdev c 251 0
    然后write的argv[1]传入绝对路径写
    write ./mdev hello 6
    read ./mdev


原创粉丝点击