嵌入式Linux驱动开发学习--韦东山老师嵌入式Linux学习

2025-01-18

1、基础内容

  • 应用、驱动、硬件:
    • 应用程序通过标准的接口访问文件,访问到驱动程序,最终到达硬件:
      • 应用程序和驱动程序涉及到用户数据和驱动数据的拷贝;
      • 驱动程序和硬件涉及到硬件寄存器实际地址和虚拟地址变量的映射;
        • 物理地址和虚拟地址映射:ioremap
        • CPU看到的是MMU映射的虚拟地址,使得启动两次的相同应用程序虽然在内存实际不同地址上但其中变量可以打印相同的虚拟地址,其他硬件也类似;
  • 驱动程序编写步骤:
    • 1)提供主设备号;
    • 2)定义file_operations 结构体,应用的标准接口能够调用起来 =》 驱动程序里也提供对应的接口;
    • 3)注册设备驱动;
    • 4)提供入口函数,放到module_init()宏;
    • 5)提供出口函数,放到'module_exit()`宏;
    • 6)提供 class_create 和 device_create 创建设备节点;

2、通用GPIO操作

  • 1)使能GPIO:用到的时候开启时钟、配置使能等;
  • 2)通过MUX_MODE将引脚配置为GPIO功能(可能有多功能复用);
  • 3)配置输入输出模式:用于输入还是用于输出,Dir;
  • 4)设置输出数据或者读取输入数据;

3、硬件操作

  • 根据硬件地址操作对应硬件位置的值或者读取——定义指针指向该地址即可;
  • volatile(易变的)使用:
    • 程序中对于同一变量连续两次赋值编译器可能会优化只执行后面的语句,因为最终结果相同;
    • 但是对于硬件来说,连续的操作可能是为了作不同的事情,不能这样优化,必须一步一步来——加上 volatile 声明,要求编译器不做优化;

4、驱动涉及的思想_面向对象_分层_分离

  • Linux驱动 = 驱动框架 + 硬件操作;

1)面向对象

  • 把事件抽象为结构体,如字符设备驱动程序抽象出一个 file_operations 结构体;

2)分层

  • 上下分层:将硬件无关操作和硬件相关操作分开为上下两层;

3)分离

  • 左右分离:将资源类型文件和硬件通用代码分离为左右两侧;

5、驱动进化之路_总线设备驱动模型

  • 驱动编写的3种方法:
  • 1)传统写法:
  • 2)总线设备驱动模型:
    • 左右分离思想的更好扩展实现 ,分别用 platform_device 结构体和 platform_driver 结构体来对应分离的硬件具体引脚等和通用硬件操作代码;
    • 然后用总线来管理他们,总线左边一系列 device,总线右边一系列 driver,通过总线将他们两两匹配;
    • 对于各种不同设备 device 的定义,可以直接用一个 .c 文件来管理 platform_device,但是会因为各种不同硬件设备出现一堆的 .c 文件;
    • 通过 .c 文件定义 dev 与 driver 的匹配:
    • 在配对成功的时候,通过 driver 的 probe 函数实现资源的注册和初始化;当设备去掉以后,调用 driver 的 remove 函数;
  • 3)使用dts文件来实现 device 的配置,dts 文件可编译为 dtb 文件,传递给内核成为 platform_device 结构体;
  • 解决用 .c 文件定义 dev 设备造成的大量重复、没有过多技术含量的代码文件,并且每次有修改就要重新编译内核 =》 用配置文件来解决,内核动态加载;

01-19

6、驱动进化之路_设备树的语法

  • 设备树语法:
    • 1)节点
      • 节点的名字后面也可以加上地址,也可以加上label方便在设备树种引用;
    • 2)节点的属性
      • 常用属性:
        • compatible,兼容;
        • status:状态,使能/禁用;
        • reg:表示寄存器地址;
        • name:节点名字,可以用来与 platform_driver 匹配;
        • device_type:节点类型;
  • dtsi :i 表示 include,语法与 dts 一致,用来给不同的单板 dts 包含——此处,可以引用label + 配合 status 属性设置为 dsabled,将公板中定义的节点而本单板用不到的节点给禁用掉;

7、驱动进化之路_内核对设备树的处理与使用

7.1 内核对设备树的处理与使用

  • 设备树是给内核、驱动程序使用的,内核与驱动程序如何使用设备树?
  • 1)dtb 中每个节点都被转换为 device_node 结构体:
  • 2)某些device_node 转换为 platform_device(并不是所有都能转换):
  • 3)driver 与设备树定义的 device 匹配:
  • 4)匹配成功后,调用 platform_driver 里面的 probe 函数获得设备树节点中的资源:
    • 使用 platform_get_resource 接口获得标准资源,如reg、interrupts获得memory资源、中断资源等;
    • 对于非特殊节点,也可以使用内核函数来获得属性;同样对于没有转化为 platform_device 的节点也可以调用内核函数获得对应属性值;
  • 5)如何修改设备树文件:

7.2 LED模板驱动程序的改造:设备树

  • 1)设备树生成的platform_device和驱动platform_driver匹配:

    • dts文件中节点指定comatible属性,platform_driver设定of_match_table并有一项指定.compatible成员,设备和驱动要能匹配上:
    • tips:GPIO通过宏指定地址映射方式:
  • 2)设备树节点指定资源后platorm_driver获得资源的方法:

    • 通过在设备树节点中添加属性,在驱动程序中通过of_property_read_u32获取属性值(即得到相关硬件资源配置值):
  • 3)调试技巧:通过设备树节点目录查找定义的设备树节点:

    • 通过platform_device找到对应platform_driver:

12-20

8、Pinctrl 子系统重要概念

  • PinCtrl子系统关键点在于通过单板的bsp工程师,提供pin引脚的可配置功能,如uart、gpio;
  • 而驱动工程师作为使用方,重点关注的是如分别给默认状态、sleep状态配置提供的function;
  • image

9、GPIO 子系统重要概念

9.1 GPIO 子系统重要概念

  • GPIO子系统关键点:通过Pinctrl指定为GPIO功能后,通过bsp工程师封装GPIO子系统,驱动工程师可以简单通过dts配置、驱动接口调用来实现对GPIO的控制
    • 用哪一组的哪一个GPIO:
    • image
  • 常用函数(实际使用时查询完善):
  • image

9.2 基于GPIO子系统的LED驱动程序

  • 本节目的:基于Pinctrl子系统和GPIO子系统来编写LED驱动程序,验证其使用的便捷;

  • 1)用法:

    • image
  • 2)DTS使用Pinctrl子系统和GPIO子系统与驱动联动逻辑流程:

    • image

9.3 IMX6ULL上机实验

  • 主要功能,基于9.2逻辑配置dts设备树,在驱动基本不修改的基础上完成硬件配置;
  • 主要流程:
    • 针对IMX6ULL可以使用NXP公司提供的图形化工具来生成Pinctrl子系统需要的配置字段,并添加到系统设备树中
      • image
      • image
    • 设备树使用Pinctrl子系统和Gpio子系统完成硬件配置:
      • image
      • 此处额外修改项是CPU的LED指示灯也用的该GPIO,需要在设备树中将对应节点属性指定为“disabled"

10、中断

10.1 异常与中断的概念及处理流程

10.2 进程线程中断的核心_栈

mmap

posted @ 2025-01-18 22:45  ~向杨而生  阅读(954)  评论(0)    收藏  举报