您的位置首页>企业动态>

如何写一个Linux设备驱动程序

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解如何写一个Linux设备驱动程序问题。首先,写这第一个Linux设备驱动的目的是为了熟悉

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解如何写一个Linux设备驱动程序问题。

首先,写这第一个Linux设备驱动的目的是为了熟悉Linux驱动的框架和编程流程,所以是通过打印出来的信息来观察程序的运行情况,并不是真正的特定设备驱动,可以和C语言编程中的“Hello World”相比。

Linux下的设备驱动架构如下图所示:

本文以first_device_driver为例。

一般来说,编写一个完整的设备驱动程序需要以下步骤:

写入first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl函数;

定义了file_operations结构,并填充了其成员函数first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl。

模块通过register_chrdev加载函数将字符设备注册到内核中;

写入口函数;

写作的退出功能;

通过module_init()修改驱动入口函数;

通过module_exit()修改驱动器退出功能;

申报模块许可证;

下面详细解释。

步骤1:在新创建的中编写图例所示的代码。c文件。

第二步:编写Makefile脚本。

值得指出的是,编写Makefile是Linux驱动工程师必备的基础,但要明白我们不需要完全掌握Makefile的语法和编程,只需要能够模仿其他项目的Makefile,写出我们想要的Makefile即可。

第三步:在相应的目录中执行make命令,生成。ko模块文件。

这一步比较简单,只需在相应的目录中输入make命令即可。

步骤4:加载。ko文件通过u盘或nfs网络文件系统进入内核。

在加载驱动程序模块之前,我们可以使用命令:cat /proc/devices来检查字符主设备号是否已被占用。Proc文件系统是Linux运行时内存中存在的文件系统,它记录了系统运行的实时信息。当系统关闭时,proc文件系统也被释放。

然后可以通过命令:insmod first_drv.ko将模块挂载到内核,通过命令:cat /proc/devices可以观察first_drv设备是否已经挂载成功。此外,还可以通过modprobe加载驱动模块。两者的区别在于modprobe可以解决加载模块时的依赖关系,这是通过file/lib/modules/# uname-r/modules . dep()找到的。bb),而insmod则不能解决模块之间的依赖问题。

步骤5:创建dev/first_driver设备节点。

使用命令:mknod /dev/first_driver 100 0创建一个设备节点。

第六步:编写测试应用程序。

的应用测试如下:

这里我们可以发现,测试程序中的open()函数实际上调用了驱动程序中的first_drv_open()函数,而write()函数实际上调用了驱动程序中的first_drv_write()函数。本质上就是这样一种把握。

行过程:用户空间的open()函数-》文件系统的sys_open()函数-》驱动的first_drv_open()函数。

另外很重要的一点,上文中图例中的程序是需要手动创建设备节点,从而提供给用户程序访问的,如此一来当驱动模块较多的时候就很麻烦,所以Linux也提供自动创建设备节点的接口,建议使用自动创建设备节点的机制。如下是自动创建设备节点的方法:

1、首先创建一个class设备类,然后在class类下,创建一个class_device,即在类下面创建类的设备;

2、在驱动入口函数中添加步骤:firstdrv_class= class_create(THIS_MODULE,“first_drv”);irstdrv_class_devs=class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,“first_drv”);

3、在驱动出口函数中添加:class_device_unregister(firstdrv_class_devs);class_destroy(firstdrv_class);

这个自动创建设备节点的功能是基于Linux支持的热拔插功能,Linux内核中每当设备出现变动时,都会处理对应的信息,使用户程序对/dev目录下的设备进行操作。

最后,此驱动程序运行的实际效果就是打印信息,这个Linux设备驱动例程可以类比于C语言中的“Hello World”例程,希望可以帮助大家初步认识Linux的设备驱动程序。

首先说明:写这个第一个Linux设备驱动程序的目的是熟悉Linux驱动的框架以及编程流程,所以是通过打印的信息来观察程序运行的情况,并不是真正的实现了某一个具体设备的驱动,可以类比于C语言编程中的“Hello World”。

Linux下的设备驱动架构如下图所示:

在本篇文章中以first_device_driver为例进行介绍

一般来说,写出完整的设备驱动程序需要如下几个步骤:

写出first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等函数;

定义file_operations结构体并填充其成员函数first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等;

模块加载函数,通过register_chrdev将字符设备注册到内核中;

写驱动的入口函数;

写驱动的出口函数;

通过module_init()来修饰驱动入口函数;

通过module_exit()来修饰驱动出口函数;

声明模块许可证;

下面进行详细讲解

步骤一:在新创建的.c文件中编写如图例中的代码

步骤二:编写Makefile脚本

值得提出的一点是,编写Makefile是Linux驱动工程师必备的基础,但是要明白我们并不需要完全的掌握Makefile的语法及编程,我们只需要能模仿着其他工程的Makefile文件写出我们自己想要的Makefile文件即可。

步骤三:在对应目录中执行make命令,生成.ko模块文件

这一步骤较为简单,只是在相应目录输入make命令即可。

步骤四:通过U盘或者nfs网络文件系统将该.ko文件加载到内核中

我们在加载驱动模块之前可以先通过命令:cat /proc/devices来查看字符主设备号是否已经被占用。proc文件系统是Linux在运行时存在于内存中的文件系统,它记录着系统运行的实时信息,当关闭系统时,proc文件系统也随之释放。

然后可通过命令:insmod first_drv.ko将模块挂载到内核, 通过命令:cat /proc/devices可以观察first_drv设备是否已经挂载成功;另外也可以通过modprobe来加载驱动模块,这两者的区别在于modprobe可以解决加载模块时的依赖关系,它是通过/lib/modules/#uname -r/modules.dep(.bb)文件来查找依赖关系的,而insmod不能解决模块间的依赖问题。

步骤五:创建dev/first_driver设备节点

通过命令:mknod /dev/first_driver 100 0 来创建设备节点。

步骤六:编写应用程序进行测试

测试的应用程序如下:

在这里我们可以发现测试程序里的open()函数实际就是调用了驱动中的first_drv_open()函数,而write()函数实际调用了驱动中的first_drv_write()函数。本质上是这样的一个执行过程:用户空间的open()函数-》文件系统的sys_open()函数-》驱动的first_drv_open()函数。

另外很重要的一点,上文中图例中的程序是需要手动创建设备节点,从而提供给用户程序访问的,如此一来当驱动模块较多的时候就很麻烦,所以Linux也提供自动创建设备节点的接口,建议使用自动创建设备节点的机制。如下是自动创建设备节点的方法:

1、首先创建一个class设备类,然后在class类下,创建一个class_device,即在类下面创建类的设备;

2、在驱动入口函数中添加步骤:firstdrv_class= class_create(THIS_MODULE,“first_drv”);irstdrv_class_devs=class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,“first_drv”);

3、在驱动出口函数中添加:class_device_unregister(firstdrv_class_devs);class_destroy(firstdrv_class);

这个自动创建设备节点的功能是基于Linux支持的热拔插功能,Linux内核中每当设备出现变动时,都会处理对应的信息,使用户程序对/dev目录下的设备进行操作。

最后,此驱动程序运行的实际效果就是打印信息,这个Linux设备驱动例程可以类比于C语言中的“Hello World”例程,希望可以帮助大家初步认识Linux的设备驱动程序。

.dfma { position: relative; width: 1000px; margin: 0 auto; } .dfma a::after { position: absolute; left: 0; bottom: 0; width: 30px; line-height: 1.4; text-align: center; background-color: rgba(0, 0, 0, .5); color: #fff; font-size: 12px; content:"广告"; } .dfma img { display: block; }
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。