3-第一个驱动开发
not helloworld ,hellomodulexiandao
1.大致流程可以总结如下:
• 实现入口函数xxx_init() 和卸载函数xxx_exit()
• 申请设备号register_chrdev_region()
• 初始化字符设备,cdev_init 函数、cdev_add 函数
• 硬件初始化,如时钟寄存器配置使能,GPIO 设置为输入输出模式等。
• 构建file_operation 结构体内容,实现硬件各个相关的操作
• 在终端上使用mknod 根据设备号来进行创建设备文件(节点) 或者自动创建(驱动使用
class_create 创建设备类、在类的下面device_create 创建设备节点)
2.但我们会发现一个问题简单的驱动会将所有的硬件信息放在代码中,如果修改驱动或二次开发会遇到问题代码重复修改麻烦,所以提出设备驱动模型分层的概念——驱动代码分成设备与驱动,设备负责提供硬件资源而驱动代码负责去使用这些设备提供的硬件资源,并由总线将它们联系起来。
• 设备(device) :挂载在某个总线的物理设备;
• 驱动(driver) :与特定设备相关的软件,负责初始化该设备以提供一些操作该设备的操作方式;
• 总线(bus) :负责管理挂载对应总线的设备以及驱动;
• 类(class) :对于具有相同功能的设备,归结到一种类别,进行分类管理;
3./sys——sysfs 虚拟文件系统
/sys/bus 目录下的每个子目录都是注册好了的总线类型。这里是设备按照总线类型分层放置的目
录结构,每个子目录(总线类型) 下包含两个子目录——devices 和drivers 文件夹;其中devices 下是
该总线类型下的所有设备,而这些设备都是符号链接,它们分别指向真正的设备(/sys/devices/下);
如下图bus 下的usb 总线中的device 则是Devices 目录下/pci()/dev 0:10/usb2 的符号链接。而drivers
下是所有注册在这个总线上的驱动,每个driver 子目录下是一些可以观察和修改的driver 参数。
/sys/devices 目录下是全局设备结构体系,包含所有被发现的注册在各种总线上的各种物理设备。
一般来说,所有的物理设备都按其在总线上的拓扑结构来显示。/sys/devices 是内核对系统中所有
设备的分层次表达模型,也是/sys 文件系统管理设备的最重要的目录结构。
/sys/class 目录下则是包含所有注册在kernel 里面的设备类型,这是按照设备功能分类的设备模型,
我们知道每种设备都具有自己特定的功能,比如:鼠标的功能是作为人机交互的输入,按照设备
功能分类无论它挂载在哪条总线上都是归类到/sys/class/input 下。
在设备模型框架下,设备驱动的开发是一件很简单的事情:先分配一个struct device 类型的变量,填充必要的信息后,把它注册到对应总线中;然后创建一个struct device_driver 类型,填充必要的
信息后注册。在合适的时机(驱动和设备匹配时),就调用驱动的probe、release 等回调函数。另外,在实际编程中较少直接使用device 和device_drivere,而是在它们上面加一层封装,比如platform device 。
1 最简单的内核模块
1 | #include<linux/module.h> |