欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

驱动开发之始,(二)字符设备驱动——Part3 简单的字符驱动实例

程序员文章站 2022-07-14 11:08:43
...

通过前面两章的知识汇总,我们了解字符设备驱动框架及其涉及的几个重要数据结构,为了加深理解,本章用一个简单的实例来演示字符设备驱动的开发过程,因为没有实际接硬件,并未实现对驱动进行复杂操作,在此只做一个初步认识,在后续的进阶部分,笔者再通过实际的字符驱动来进一步分析。

1.字符设备驱动 hello_module.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kernel.h>

static int major = 88;
static int minor = 0;
static dev_t devno;
static struct cdev  cdev;

static int hello_open(struct inode *inode, struct file *filep)
{
    printk(KERN_ALERT "Hello lijunnan!\n");
    return 0;
}

struct file_operations file_ops = 
{
    .open = hello_open
};


static int hello_init(void)
{
    int ret;
    printk(KERN_ALERT "hello_init!\n");     

    devno = MKDEV(major, minor);
    ret = register_chrdev_region(devno, 1, "hello");
    if(ret < 0)
    {
        printk("register chrdev region failed!\n");
        return ret;
    }

    cdev_init(&cdev, &file_ops);
    ret = cdev_add(&cdev, devno, 1);
    if(ret < 0)
    {
        printk("cdev add failed!\n");
        return ret;
    }
    return 0;
}

static void hello_exit(void)
{
    cdev_del(&cdev);
    unregister_chrdev_region(devno, 1);
    printk(KERN_ALERT "See you next time!\n");     

}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("LiJunnan");

a. 首先需要申请一个设备号,在此笔者通过动态分配获取一个dev_t,即register_chrdev_region()函数

b. 初始化cdev结构体,调用cdev_init(),将cdev和file_operations关联起来

c. 注册cdev结构,告诉内核该结构的信息,调用cdev_add()

d. 在file_operations结构中定义了open操作方法,通过系统调用open实现

e. 在卸载函数中需要移除字符设备,调用cdev_del(),并释放设备号unregister_chrdev_region()

2.应用程序hello_app.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
    int fd = 0;

    fd = open("/dev/hello_module", O_RDWR);
    if(fd < 0)
    {
        printf("open failed!\n");
        return -1;
    }
    
    printf("hello lijunnan\n");

    close(fd);
    return 0;
}

首先,我们安装内核模块,insmod hello_module.ko,在/proc/devices文件可以看到安装的内核模块

驱动开发之始,(二)字符设备驱动——Part3 简单的字符驱动实例

在系统与设备通信前,需要创建一个设备文件,这个文件存放在/dev目录下,系统默认情况下就已经成立了很多设备文件,我们也可以手动新建一些设备文件,使用mknod命令,格式如下:

mknod DEVNAME 设备类型 MAJOR MINOR

驱动开发之始,(二)字符设备驱动——Part3 简单的字符驱动实例

注意:

1.需要使用超级用户权限创建设备文件

2.设备文件的主设备号需要与内核模块设备号一致

3.修改新建设备文件的读写权限

最后,在执行./hello

驱动开发之始,(二)字符设备驱动——Part3 简单的字符驱动实例

相关标签: Linux驱动开发