Linux驱动开发(3)——设备树

一、驱动和设备分离

设备树可以统一管理设备,存放所有设备信息。

1、设备树文件类型:

  • dts:设备树源文件
  • dtsi:设备树头文件
  • dtb:编译好的二进制设备树文件,可直接使用
  • DTC:编译工具

2、设备树节点语法:

cs 复制代码
设备名{
    #address-cells = <1>;//每个地址所占字节
    #size-cells = <1>;//地址大小所占字节
   
    // 寄存器物理地址 + 长度  可以写多组
    reg = <地址1 长度1
           地址2 长度2
           地址3 长度3>;

    status = "okey";//设备可用状态
}

3、设备树函数接口:

1).函数:struct device_node *of_find_node_by_path(const char *path);

  • 功能:通过路径获得设备树节点
  • 参数:@path --- 设备树节点全路径(比如'/myled')

2).函数:int of_property_read_string(struct device_node *np, const char *propname, const char **out_string);

  • 功能:读取属性中的字符串值
  • 参数:@np --- 设备树节点,@propname --- 要读的属性名,@out_string --- 存放缓冲区

3).函数:void __iomem *of_iomap(struct device_node *np, int index);

  • 功能:设备树中的物理地址映射为内核虚拟地址
  • 参数:@np --- 设备树节点,@index --- reg数组的下标,从0开始)

二、驱动分层:

设备有4 类寄存器:

  • 引脚复用
  • 电气属性
  • GPIO 方向
  • GPIO 数据

将寄存器的配置移入设备树(Device Tree),由 Linux 内核的 pinctrl 子系统 和 GPIO 子系统完成。

1、pinctrl子系统:操作iomuxrc的寄存器

1).pinctrl方案定义

cs 复制代码
pinctrl_myled:myledgrp{//方案名:组名
    fsl,pins = <
        //引脚配置宏   电器属性参数
    >;
}

2).pinctrl方案使用

cs 复制代码
设备树节点{
    pinctrl-names = "default";//默认按照pinctrl方案定义配置
    pinctrl-0 = <&pinctrl方案名>;
};

2、GPIO子系统:操作GPIO的寄存器

cs 复制代码
设备树节点{
    gpio-led = <&gpio控制器编号 gpio引脚号 有效电平>;
};

1).函数:int of_get_named_gpio(struct device_node *np, const char *propname, int index);

  • 功能:从设备树节点中解析并获取指定GPIO硬件编号
  • 参数:@np --- 设备树节点,@propname --- GPIO子系统名,@index --- 方案编号,从0开始
  • 返回值:成功返回引脚编号,失败返回-1

2).函数:int devm_gpio_request(struct device *dev, unsigned gpio, const char *label);

  • 功能:或得单个GPIO描述符,设备卸载时自动释放
  • 参数:@dev --- 设备,@gpio --- 要占用的引脚编号,@label --- 标明占用资源的驱动

3).函数:int gpio_direction_output(unsigned gpio, int value);

  • 功能:将GPIO引脚设置为输出模式
  • 参数:@gpio --- 引脚编号,@value --- 初始电平

4).函数:int gpio_direction_input(unsigned gpio);

  • 功能:将GPIO引脚设置为输入模式

5).函数:int gpio_get_value(unsigned int gpio);

  • 功能:读取输入引脚电平

6).函数:void gpio_set_value(unsigned int gpio, int value);

  • 功能:设置输出引脚电平

三、Linux中断

Linux 内核有中断子系统,专门管理所有硬件中断,不用我们直接操作寄存器配置中断。中断子系统分为:顶半部 + 底半部。

顶半部:

  • 硬件一触发中断立刻执行
  • 执行时间必须很短,只做最简单的事:标记中断、读取按键电平
  • 不能延时、不能睡眠、不能做耗时操作

底半部:

  • 把耗时、复杂的任务挪到底半部执行
  • 顶半部快速退出,不占用 CPU,提高系统响应速度
  • 常见实现:工作队列、tasklet 等
cs 复制代码
设备节点{
    interrupt-parent = <&gpio1>;//中断控制器
    interrupts = <15 IRQ_TYPE_EDGE_FALLING>;//触发方式,例如15下降沿触发
};
相关推荐
小坏讲微服务2 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
打工仔折腾 AI3 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战
MATLAB代码顾问3 小时前
Simulink PI 参数扫描与批量仿真完整 MATLAB 代码
开发语言·matlab
Want5954 小时前
Python跳动的爱心②
开发语言·python·数学建模
小羊没烦恼!4 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
爱吃香菜的初学者5 小时前
十六.Linux——多线程(2)
linux·运维·开发语言
jeo陽5 小时前
04-循环实战:素数、最大公约数、级数求和与枚举法
c语言·开发语言·数据结构
Highcharts.js5 小时前
AI图表开发工具Highcharts Assist|自然语言生成图表代码
javascript·人工智能·highcharts·开发神器
暖核5 小时前
kubeadm 集群运维:Worker 节点下线删除、整套集群销毁重建指南
运维·开发语言·php
志尊宝5 小时前
Vue3 零基础每日笔记(087):Vue3 高频面试题(下)
前端·javascript·vue.js·笔记·ecmascript·#vue.js