700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Linux驱动编程 step-by-step (一)驱动程序的作用

Linux驱动编程 step-by-step (一)驱动程序的作用

时间:2023-04-26 16:06:06

相关推荐

Linux驱动编程 step-by-step (一)驱动程序的作用

驱动程序的作用:

简单来说 驱动程序就是使计算机与设备通信的特殊的代码,在作单片机时候(无OS)我们自己定义接口及自定义的结构来操作相关硬件,而在有OS的模式下我们操作的硬件是去实现对应的接口(这些接口是已定义好的,我们需要实现这些接口)而无需自己定义接口,这样既能正确的控制设备。又能很好的维护(如果需要升级驱动,上边的应用程序不需要改变)

编写驱动考虑的因素

提供给用户更多的选项保持用户操作的简单性编写驱动的时间

驱动分类:

字符设备:能够像字节流(类似文件)一样被访问的设备(至少实现open, close, read ,write等功能)快设备: 用户空间接口与字符设备相同, 内部实与字符设备完全不同(可以被随即访问,一般在类UNIX系统中快设备的读取每次只能读一整块在linux可以操作任意字节)网络设备:网络通路通过网络设备形成,能够与主机交换数据的设备

内核功能划分:

进程管理(PM):进程的创建与撤销,在单个或者多个CPU上实现多进程的抽象内存管理(MM):管理内存分配及回收的策略文件系统(FS/VFS): Linux 非常依赖于文件系统,内核在没有结构的硬件系统上构造结文件系统,而文件抽象在整个系统中会广泛使用,Linux支持多种文件系统类型设备控制:驱动程序,操控硬件以及相应总线设备网络(NET): 在网络接口于应用程序之间传输数据。

好了 理论行得东西介绍的差不多了,下边说点有用的,内核的驱动可以做成模块在需要的时候装载,在不需要的时候卸载

我们在编写用户程序的时候总喜欢从编写hello world 写起 , 在内核驱动模块也是一样,下边是一个hello_world的一个模块

//hello_world.c #include<linux/init.h> #include<linux/module.h> MODULE_LICENSE("GPL"); staticinthello_init(void) { printk(KERN_ALERT"hellomodule\n"); return0; } staticvoidhello_exit(void) { printk(KERN_ALERT"hellomoduleexit\n"); } module_init(hello_init); module_exit(hello_exit);

以及对应的Makefile

ifneq($(KERNELRELEASE),) #callfromkernelbuildsystem obj-m:=hello_world.o #ifweneedmorethanonesourcecodetobuildthemodule #weshouldusethevariablebelow:example:modules-objs:=file1.ofile2.o modules-objs:= else #kernelPTAH KERNELDIR?=/lib/modules/$(shelluname-r)/build PWD:=$(shellpwd) modules: $(MAKE)-C$(KERNELDIR)M=$(PWD)modules endif clean: rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versions

有几点与用户空间程序不同的地方

模块程序没有main函数(那么程序入口在哪里?)打印函数使用的printk 而不是用户空间的printf 而且使用方式不一样

模块的编译不是通常的方式头文件不是常见的那些头文件

以及编译之后不会产生可执行文件,而是 .ko 文件

...

模块没有main函数,在装载模块 insmod 时会调用module_init注册的函数 此处为hello_init

在模块卸载remod时 会调用module_exit注册的函数 此处为hello_exit

在module_init 注册的函数主要是进行初始化,分配内存, 注册设备等

而module_exit中注册的函数与之相反, 设备注销, 释放内存等

具体的编译模块的Makefile我在另一篇文章中有说到 此处不再赘述

内核的打印函数使用printk去打印信息, printk不支持浮点类型, 在printk中可以加入信息级别有7中

#defineKERN_EMERG"<0>"/*systemisunusable*/ #defineKERN_ALERT"<1>"/*actionmustbetakenimmediately*/ #defineKERN_CRIT"<2>"/*criticalconditions*/ #defineKERN_ERR"<3>"/*errorconditions*/ #defineKERN_WARNING"<4>"/*warningconditions*/ #defineKERN_NOTICE"<5>"/*normalbutsignificant*/ #defineKERN_INFO"<6>"/*informational*/ #defineKERN_DEBUG"<7>"/*debug-levelmessages*/ 对应与不同的错误等级 选择不懂的option, 并做不同的处理, 小于一定等级的信息会直接打印到终端(非X-window下的终端),可以使用dmesg来查看全部的打印信息

编译内核的头文件是在/lib/modules/$(shelluname-r)/build/include下得,而不是用户模式下得/usr/include

编译后不会生产可执行文件,会生成一个.ko的文件

使用insmodxxx.ko去装载模块

使用lsmod去查看已装载的模块

使用rmmodxxx去卸载相应模块(卸载是不带.ko)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。