3.字符驱动框架

一.驱动的种类 :
        字符驱动/字符设备 (像子节流一样访问的设备,led)
        块驱动 / 块设备  (通过内存缓冲区进行访问,可以随机读取的设备 硬盘)、
        网络驱动 / 网络设备(能够与其他主机发生数据交换的设备 蓝牙、网卡驱动)
        
        
二.总线/设备/驱动关系:
        总线在Linux中有两种存在:一种是设备本身就是一个总线设备,则需要将设备/驱动挂载到其总线上即可;另一种是虚拟总线,也叫平台总线或者platform总线
        总线用于匹配系统中存在的 设备 和 驱动。无论是注册设备还是驱动,都需要向总线进行汇报即注册。
     设备注册的方法:  
        设备的注册在板极支持包的配置文件(arch/arm/mach-exynos/mach-itop4412.c)中进行。所有板载专有设备的声明都会在这里面,驱动是通过编写源代码文
        件,编译成.ko模块后动态或静态添加至系统。Linux系统自动完成设备和驱动的匹配工作。(热插拔)

三.字符驱动的基本框架:

   1.一般设备驱动的框架:(支持udev设备管理方法的驱动框架)
        (1).模块加载函数--module_init(function) 模块卸载函数--module_exit(function)
        (2).定义主次设备号,通过alloc_chrdev_region()来动态申请设备号。建议使用动态方式来获取设备号,防止冲突。用后要释放。
        (3).定义class结构体指针,通过class_create()来创造一个结构体类指针,用来服务于device_create。
        (4).定义设备描述结构体cdev对象,并通过alloc_cdev()来生成。
        (5).定义驱动的一组操作方法file_operations。通过cdev_init()来初始化cdev结构体对象,并添加fs对象。通过cdev_add()函数将其添加到系统。
      最后通过device_create()来创建设备节点,并将其注册到系统。
        (6).生成.ko模块,编写Makefile脚本语言。通过Linux源码树的 Makefile 来搜集资源和信息,进行模块的编译。。在Linux系统中没有提供像STM32开发
      提供的IDE,所以只能通过脚本语言写Makefile编译文件来生成可执行的二进制文件。  
   
   2.杂项设备的驱动框架:
   
        杂项设备引入的原因: 统一了主设备号为10,方便编程,减少了编程的步骤;  将无法归类的特殊设备进行归类,节约主设备号。当一个驱动要驱动多项设备
     时,则不能使用杂项设备。因为主设备号已经固定了。
        
        (1).模块加载函数--module_init(misc_init) 模块卸载函数--module_exit(misc_exit)
        (2).在misc_init /misc_exit 分别注册/卸载杂项设备
        (3).创建 miscdev 结构体实例对象,再创建驱动操作file_operations结构体实例对象。然后对各操作函数(ioctl/read/open..)进行定义。
        
   3.platform设备的框架
   
        平台设备引入的原因:platform平台设备驱动是基于Linux的总线-设备-驱动的模型。总线用于实现注册到系统中的设备和驱动匹配。platform
     在Kernel-2.6之后引入了platform机制,为了实现对设备所占用资源的统一管理。将资源和驱动分开,便于程序的移植和复用。在设备和注册设备中实现
     对使用硬件资源,匹配信息进行说明。而在驱动程序中通过API对资源进行调用,隔离BSP和驱动。
     
     其中struct platform_device和struct platform_driver是对structdevice_driver 和 struct device的进一步封装而来。资源resource是
     对所占用硬件信息的抽象。例如:内存/IO/DMA/IRQ/BUS
     
        平台设备驱动框架分为两个部分:platform_device部分和platform_driver部分。
                
        (1). platform设备的注册(把平台设备添加到总线) struct platform_device
             在mach-itop4412.c 源文件中通过注册平台设备结构体 platform_device xxx ,然后再通过一个platform device结构体将所有的平台设备
          进行初始化。
          
        (2).平台设备驱动的注册(把驱动添加到平台总线中去) struct platform_driver
        
              ***平台设备的驱动和一般字符驱动只是在框架上有些许差异,platform驱动注册设备和申请系统资源的位置在probe探测函数中,而一般的字符驱动
              注册设备和申请系统资源的位置是在驱动注册函数中。*********
              
              <1>. 定义一个platform_driver的实例对象,然后定义结构体中的函数--probe/suspend/resume/..。
              <2>. 在probe函数中进行驱动的注册过程 / 杂项设备注册或者一般字符驱动注册         
              <3>. 创建驱动操作file_operations结构体对象实例,并进行初始化定义。
              <4>. 在模块初始化-退出函数中,将定义的platform_driver对象进行注册和销毁。
              

     

原文地址:https://www.cnblogs.com/nyqm/p/7954680.html