• 字符设备驱动框架


    应用程序通过标准接口(C Library)调用驱动程序。

    C Library 通过 swi 指令进入内核。

     

    字符设备的注册

    int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)

    a、函数说明:

    Param1:主设备号

    Param2:设备名字

    Param3:文件操作结构体指针

    Return:当传入的主设备号为0时(系统自动分配主设备号),函数返回值为系统自动分配的主设备号

    b、这个函数在内核中最简单的实现方式:

    猜想:在内核里,声明一个struct file_operations类型的chrdev的数组,以major为下标;

    当调用这个函数时,在指定下标的数组成员内,填充file_operations结构,实现驱动设备的注册。

       

    驱动的使用方法

    动态加载驱动的方法:

    insmod *.ko

       

    手动创建设备节点:

    mknod /dev/xxx c 111 0

     

    应用程序怎么操作底层设备呢?

    fd = open("/dev/xxx", O_RDWR);

    write(fd, &val, 4);

    通过文件描述符,实现对底层设备的操作

       

    如何自动创建设备节点?

    mdev根据系统信息自动创建设备节点。

       

    如何生成系统信息?

    在加载驱动时生成,在入口函数实现。

       

    为什么系统可以根据系统的设备信息动态生成/删除设备节点?

    /etc/init.d/rcS 脚本文件,有如下内容:

    echo /sbin/mdev > /proc/sys/kernel/hotplug

       

    系统设备信息:

    /sys/class/class_dev

    class目录下,每一个class_dev存储一个设备驱动信息,mdev根据这个信息生成设备节点。

       

    实际上,

    对于驱动程序:(主设备号)

    ①由系统自动分配主设备号

    ②由用户指定主设备号

    对于应用程序:(设备节点)

    ①手动创建设备节点

    ②由系统自动创建/删除设备节点

       

    六、驱动程序基本框架

    ①实现驱动程序;

    ②声明并初始化file_operations结构体;(把驱动程序的函数指针填充到结构体中)

    ③编写入口函数,并在入口函数中注册设备驱动(register_chrdev(0, "drv_name", drv_fops););

    ④编写出口函数,并在出口函数中卸载驱动(unregister_chrdev(major, "drv_name"););

    ⑤修饰入口函数(module_init("入口函数"););

    ⑥修饰出口函数(module_exit("出口函数"););

       

    七、实例

    driver.c

    1 #include <linux/module.h>
    2 #include <linux/kernel.h>
    3 #include <linux/fs.h>
    4 #include <linux/init.h>
    5 #include <linux/delay.h>
    6 #include <asm/uaccess.h>
    7 #include <asm/irq.h>
    8 #include <asm/io.h>
    9 #include <asm/arch/regs-gpio.h>
    10 #include <asm/hardware.h>
    11
    12 int major;
    13 static struct class *simple_class;
    14 static struct class_device *simple_class_dev;
    15
    16 static int simple_open(struct inode *inode, struct file *file);
    17 static ssize_t simple_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
    18

    19 static struct file_operations simple_fops = {
    20         .open = simple_open,
    21         .write = simple_write,
    22         .owner = THIS_MODULE,
    23 };
    24
    25 static int simple_open(struct inode *inode, struct file *file)
    26 {
    27         printk("simple_open ");
    28         return 0;
    29 }
    30
    31
    32 static ssize_t simple_write(struct file *file, const char __user *buf,
    33
    size_t count, loff_t *ppos)
    34 {
    35         printk("simple_write ");
    36         return 0;
    37 }
    38
    39 static int __init simple_init(void)
    40 {
    41         major = register_chrdev(0, "simple", &simple_fops);
    42         simple_class = class_create(THIS_MODULE, "myDrv");
    43         simple_class_dev = class_device_create(simple_class, NULL, MKDEV(major, 0), NULL, "simple");
    44         
    45         return 0;
    46 }
    47
    48 static void __exit simple_exit(void)
    49 {
    50         unregister_chrdev(major, "simple");
    51         class_device_unregister(simple_class_dev);
    52         class_destroy(simple_class);
    53         return;
    54 }
    55
    56 module_init(simple_init);
    57 module_exit(simple_exit);
    58
    59 MODULE_LICENSE("GPL");

       

    app.c

    1 #include <sys/types.h>
    2 #include <sys/stat.h>
    3 #include <fcntl.h>
    4 #include <stdio.h>
    5
    6 int main (void)
    7 {
    8         int fd;
    9         int val = 1;
    10         
    11         printf("test app: ");
    12         
    13         fd = open("/dev/simple", O_RDWR);
    14         if(fd < 0)
    15         {
    16                 printf("open failed!---%d--- ", fd);
    17                 return 0;
    18         }
    19         write(fd, &val, 4);
    20         
    21         return 0;        
    22 }

     

    Makefile

    1 KERN_DIR = /work/system/linux-2.6.22.6
    2
    3 all:
    4         make -C $(KERN_DIR) M=`pwd` modules
    5

    6 clean:
    7         make -C $(
    KERN_DIR) M=`pwd` modules clean
    8         
    rm -rf modules.order

    9
    10 obj-m += simple.o

     

     

       

  • 相关阅读:
    jquery获得url的get参数
    WampServer更改或重置数据库密码
    phpexcel乱码问题
    5kcrm增加权限管理中的模块(签到统计)
    windows关于定时执行的php脚本
    php 中引入邮箱服务 , 利用第三方的smtp邮件服务
    thinkphp 多个字段的不同关系的查询条件实现 .
    redis与memcached有什么区别
    MYSQL语句大全
    使用HttpClient工具类发起Restful API调用
  • 原文地址:https://www.cnblogs.com/lilto/p/11878237.html
Copyright © 2020-2023  润新知