// 包含头文件定义宏和常量 #include dt-bindings/interrupt-controller/arm-gic.h #include dt-bindings/gpio/gpio.h #include dt-bindings/clock/stm32mp1-clks.h #include dt-bindings/reset/stm32mp1-resets.h / { // 1. 根节点标准属性 model Generic SoC Demo Board; compatible vendor,demo-board, vendor,generic-soc; // 指定地址范围#address-cells2: 64位地址#size-cells2: 64位大小 #address-cells 2; #size-cells 2; // 2. 内存节点必需 memory80000000 { device_type memory; reg 0x0 0x80000000 0x0 0x80000000; // 起始地址2GB, 大小2GB }; // 3. 保留内存CMA/DMA/安全内存 reserved-memory { #address-cells 2; #size-cells 2; ranges; cma: cma90000000 { compatible shared-dma-pool; reusable; reg 0x0 0x90000000 0x0 0x10000000; // 256MB CMA linux,cma-default; }; }; // 4. 中断控制器GIC-V2示例 interrupt-controllerc000000 { compatible arm,cortex-a15-gic; reg 0x0 0xc000000 0x0 0x1000, // GICD 0x0 0xc010000 0x0 0x1000; // GICC interrupt-controller; #interrupt-cells 3; // SPI/PPI编号, 触发类型, CPU掩码 interrupts GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH; }; // 5. 系统时钟源OSC clocks { osc24m: osc24m { compatible fixed-clock; #clock-cells 0; clock-frequency 24000000; }; }; // 6. 电源管理REGULATOR vcc3v3: regulator-3p3v { compatible regulator-fixed; regulator-name vcc3v3; regulator-min-microvolt 3300000; regulator-max-microvolt 3300000; regulator-always-on; regulator-boot-on; vin-supply vdd5v0; // 引用其他regulator }; // 7. 总线节点示例 soc { compatible simple-bus; #address-cells 1; // 32位地址 #size-cells 1; // 32位大小 ranges 0x0 0x0 0x40000000 0x10000000; // 映射到0x40000000 // 8. GPIO控制器 gpio0: gpio50002000 { compatible vendor,gpio-controller; reg 0x50002000 0x400; interrupts GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH; gpio-controller; #gpio-cells 2; // gpio号, 标志位 interrupt-controller; #interrupt-cells 2; // IRQ号, 触发类型 gpio-ranges gpio0 0 0 32; // 映射到Linux GPIO号0-31 clocks rcc GPIO0_CLK; // 引用时钟 clock-names gpio; pinctrl-names default; pinctrl-0 gpio0_default_pins; // 驱动API: devm_clk_get(dev, gpio) // 驱动API: devm_regulator_get(dev, vcc3v3) // 设备树属性名对应 }; // 9. I2C控制器 i2c0: i2c50001000 { compatible vendor,i2c-controller; reg 0x50001000 0x400; interrupts GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH; #address-cells 1; // I2C地址是7/10位 #size-cells 0; // I2C设备无长度 clocks rcc I2C0_CLK; clock-names i2c; i2c-scl-rising-time-ns 100; i2c-scl-falling-time-ns 20; status okay; // I2C子设备: 温度传感器 temp-sensor48 { compatible ti,tmp112; reg 0x48; // I2C地址 vcc-supply vcc3v3; interrupts-extended gpio0 5 IRQ_TYPE_EDGE_RISING; // 驱动API: i2c_new_client_device() // 内核自动创建 // 驱动API: devm_regulator_get(dev, vcc) // 驱动API: gpiod_get(dev, alert, GPIOD_IN) // alert是GPIO label }; // EEPROM eeprom50 { compatible atmel,24c16; reg 0x50; pagesize 16; address-width 8; }; }; // 10. SPI控制器 spi0: spi50003000 { compatible vendor,spi-controller; reg 0x50003000 0x400; interrupts GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH; #address-cells 1; // CS号 #size-cells 0; clocks rcc SPI0_CLK; clock-names spi; status okay; // SPI子设备: Flash flash0 { compatible jedec,spi-nor; reg 0; // CS0 spi-max-frequency 50000000; vcc-supply vcc3v3; partitions { compatible fixed-partitions; #address-cells 1; #size-cells 1; bootloader0 { label u-boot; reg 0x0 0x80000; }; }; }; // SPI设备: ADC adc1 { compatible ti,ads7846; reg 1; spi-max-frequency 2000000; interrupt-parent gpio0; interrupts 6 IRQ_TYPE_EDGE_FALLING; vcc-supply vcc3v3; pinctrl-names default; pinctrl-0 spi0_cs1_pin; }; }; // 11. PWM控制器 pwm0: pwm50004000 { compatible vendor,pwm; reg 0x50004000 0x400; #pwm-cells 2; // channel, period_ns clocks rcc PWM0_CLK; status okay; }; // 12. UART控制器 uart0: serial50005000 { compatible vendor,uart; reg 0x50005000 0x1000; interrupts GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH; clocks rcc UART0_CLK; clock-names uart; status okay; current-speed 115200; pinctrl-names default, sleep; pinctrl-0 uart0_pins_active; pinctrl-1 uart0_pins_sleep; }; // 13. DMA控制器 dma0: dma50006000 { compatible vendor,dma; reg 0x50006000 0x1000; interrupts GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH; #dma-cells 1; // channel编号 dma-channels 8; }; // 14. ADC控制器 adc0: adc50007000 { compatible vendor,adc; reg 0x50007000 0x400; interrupts GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH; clocks rcc ADC0_CLK, adc_vref_clk; clock-names adc, vref; vref-supply vref_buf; // 关键属性名与API对应关系 #io-channel-cells 1; status okay; // 驱动API: devm_regulator_get(dev, vref) // 驱动API: devm_clk_get(dev, adc) }; // 15. USB控制器 usb0: usb50008000 { compatible vendor,usb-otg; reg 0x50008000 0x1000; interrupts GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH; clocks rcc USB0_CLK, rcc USB0_PHY_CLK; clock-names otg, phy; phys usbphy0 0; phy-names usb2-phy; dr_mode otg; // 可设为host, peripheral status okay; }; // 16. Ethernet控制器 eth0: ethernet50009000 { compatible vendor,eth; reg 0x50009000 0x1000; interrupts GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH; clocks rcc ETH0_CLK, rcc ETH0_PTP_CLK; clock-names stmmaceth, ptp_ref; phy-mode rgmii; phy-handle phy0; snps,reset-gpio gpio0 7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 10000 10000; status okay; mdio0 { compatible snps,dwmac-mdio; #address-cells 1; #size-cells 0; phy0: ethernet-phy0 { reg 0; vcc-supply vcc3v3; }; }; }; // 17. 触摸屏控制器 touch: touch5000a000 { compatible goodix,gt911; reg 0x5d; // I2C地址实际挂在i2c0上 vdd-supply vcc3v3; reset-gpio gpio0 8 GPIO_ACTIVE_LOW; irq-gpio gpio0 9 IRQ_TYPE_EDGE_RISING; touchscreen-size-x 800; touchscreen-size-y 480; // 驱动API: devm_regulator_get(dev, vdd) // 驱动API: devm_gpiod_get(dev, reset, GPIOD_OUT_LOW) }; // 18. 显示控制器DRM display0: display5000b000 { compatible vendor,display; reg 0x5000b000 0x1000; interrupts GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH; clocks rcc DISPLAY_CLK, rcc DISPLAY_PIX_CLK; clock-names display, pixel; // 关键供电属性 vcc-supply vcc3v3; iovcc-supply vcc1v8; ports { #address-cells 1; #size-cells 0; port0 { reg 0; lcd_panel: endpoint { remote-endpoint panel_in; }; }; }; }; // LCD面板 panel { compatible panel-lvds; vcc-supply lcd_pwr; iovcc-supply vcc1v8; backlight backlight; port0 { reg 0; panel_in: endpoint { remote-endpoint lcd_panel; }; }; }; // 背光控制PWMGPIO backlight { compatible pwm-backlight; pwms pwm0 0 50000; // channel 0, 50k ns period brightness-levels 0 128 255; default-brightness-level 128; enable-gpios gpio0 10 GPIO_ACTIVE_HIGH; }; }; // 19. 复位控制器 rstc: reset-controller5000c000 { compatible vendor,reset; reg 0x5000c000 0x200; #reset-cells 1; }; // 20. 时钟控制器CCF rcc: rcc5000d000 { compatible vendor,rcc; reg 0x5000d000 0x1000; #clock-cells 1; #reset-cells 1; // 内部时钟 osc24m: osc24m_ck { compatible fixed-factor-clock; clocks osc24m; clock-div 1; clock-mult 1; }; // 门控时钟对应各外设 GPIO0_CLK: gpio0_clk { compatible gate-clock; reg 0x100; clocks osc24m; #clock-cells 0; }; I2C0_CLK: i2c0_clk { compatible gate-clock; reg 0x104; clocks osc24m; }; SPI0_CLK: spi0_clk { /* ... */ }; PWM0_CLK: pwm0_clk { /* ... */ }; UART0_CLK: uart0_clk { /* ... */ }; ADC0_CLK: adc0_clk { /* ... */ }; USB0_CLK: usb0_clk { /* ... */ }; ETH0_CLK: eth0_clk { /* ... */ }; }; // 21. 引脚控制器PINCTRL pinctrl { compatible vendor,pinctrl; reg 0x5000e000 0x1000; gpio0_default_pins: gpio0-default { pins { pinmux PIN_GPIO0_0, PIN_GPIO0_1; bias-pull-up; drive-strength 10; // mA }; }; uart0_pins_active: uart0-active { pins { pinmux PIN_UART0_TX, PIN_UART0_RX; bias-pull-up; }; }; uart0_pins_sleep: uart0-sleep { pins { pinmux PIN_UART0_TX, PIN_UART0_RX; drive-strength 0; // 高阻 }; }; spi0_cs1_pin: spi0-cs1 { pins { pinmux PIN_SPI0_CS1; bias-pull-up; }; }; }; // 22. aliases别名方便访问 aliases { serial0 uart0; i2c0 i2c0; spi0 spi0; ethernet0 eth0; }; // 23. chosen内核参数 chosen { stdout-path serial0:115200n8; bootargs consolettyS0,115200 root/dev/mmcblk0p2 rw rootwait; }; // 24. LEDs leds { compatible gpio-leds; pinctrl-names default; pinctrl-0 leds_pins; led-red { label red; gpios gpio0 12 GPIO_ACTIVE_HIGH; linux,default-trigger heartbeat; }; led-blue { label blue; gpios gpio0 13 GPIO_ACTIVE_LOW; default-state off; }; }; // 25. GPIO按键 keys { compatible gpio-keys; pinctrl-names default; pinctrl-0 keys_pins; key-power { label Power Button; linux,code KEY_POWER; gpios gpio0 14 GPIO_ACTIVE_LOW; debounce-interval 50; // ms }; }; // 26. 热管理 thermal-zones { cpu_thermal: cpu-thermal { polling-delay 1000; thermal-sensors temp_sensor 0; trips { cpu_passive: cpu-passive { temperature 75000; // 75°C hysteresis 2000; type passive; }; cpu_hot: cpu-hot { temperature 90000; hysteresis 2000; type hot; }; }; }; }; }; 用api 解析一、核心映射规则 规则1Regulator供电属性 设备树使用 name-supply 格式驱动代码使用 devm_regulator_get(dev, name) // 设备树 vcc-supply vcc3v3; // 驱动代码 struct regulator *vcc devm_regulator_get(dev, vcc); // 去掉 -supply 规则2Clock时钟属性 clock-names xxx → devm_clk_get(dev, xxx) // 设备树 clocks rcc UART0_CLK; clock-names uart; // 驱动代码 struct clk *uart_clk devm_clk_get(dev, uart); // 用 clock-names 的值 规则3GPIO属性 gpios → gpiod_get(dev, label, flags) label 或节点名决定参数 // 设备树 reset-gpio gpio0 8 GPIO_ACTIVE_LOW; 规则5PHANDLE引用 node → of_parse_phandle() // 驱动代码 struct gpio_desc *reset_gpio devm_gpiod_get(dev, reset, GPIOD_OUT_LOW); // reset 来自属性名 reset-gpio 去掉 -gpio 规则4中断属性 interrupts ... → platform_get_irq() 或 irq_of_parse_and_map() // 设备树 interrupts GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH; // 驱动代码 int irq platform_get_irq(pdev, 0); // 获取第一个中断号 // 设备树 phy-handle phy0; // 驱动代码 struct device_node *phy_node of_parse_phandle(np, phy-handle, 0); 二、逐节点API解析 1. 根节点 (/) // 获取model属性 const char *model of_property_read_string(np, model, NULL); // 获取compatible const char *compatible of_property_read_string_array(np, compatible, ...); 2. 内存节点 (memory80000000) // 内核自动解析驱动无需操作 // 可通过sysfs查看: /sys/firmware/devicetree/base/memory80000000/reg 3. 保留内存 (reserved-memory) // CMA区域自动注册到DMA子系统 // 驱动使用: dma_alloc_coherent(dev, size, dma_addr, GFP_KERNEL); 5. 时钟 (clocks) // 固定时钟被CCF(通用时钟框架)自动注册 struct clk *osc clk_get(NULL, osc24m); // 使用label作为名称 6. Regulator (vcc3v3) // 固定电压regulator struct regulator *reg devm_regulator_get(dev, vcc3v3); // regulator-name 7. GPIO控制器 (gpio50002000) // 重要gpio-ranges属性 // 映射硬件GPIO号到Linux全局GPIO号 // 驱动使用gpiod API时无需关心硬件编号 // 时钟获取 struct clk *gpio_clk devm_clk_get(dev, gpio); // 对应clock-names // Regulator获取如果有时钟就需要regulator struct regulator *vcc devm_regulator_get(dev, vcc3v3); 8. I2C控制器 (i2c50001000) // I2C驱动核心代码 struct platform_device *pdev; struct resource *res; void __iomem *base; // 1. 获取内存资源 res platform_get_resource(pdev, IORESOURCE_MEM, 0); base devm_ioremap_resource(dev, res); // 2. 获取中断 int irq platform_get_irq(pdev, 0); // 3. 获取时钟 struct clk *i2c_clk devm_clk_get(dev, i2c); // 4. 获取Pinctrl struct pinctrl *pinctrl devm_pinctrl_get_select(dev, default); // 5. 获取regulator可选 struct regulator *vcc devm_regulator_get_optional(dev, vcc); 9. I2C子设备 (temp-sensor48) // 驱动使用regmap或直接I2C API // 1. 自动获取regulator关键 struct regulator *vcc devm_regulator_get(dev, vcc); // 来自vcc-supply // 2. 获取中断GPIO使用label参数 struct gpio_desc *alert_gpio devm_gpiod_get(dev, alert, GPIOD_IN); int irq gpiod_to_irq(alert_gpio); // 3. 获取中断号如果使用了interrupts-extended int irq platform_get_irq(pdev, 0); // 4. I2C地址自动从reg属性解析 // 驱动通过client-addr获取 10. SPI控制器 (spi50003000) // 与I2C类似 struct clk *spi_clk devm_clk_get(dev, spi); struct resource *res platform_get_resource(pdev, IORESOURCE_MEM, 0); 11. SPI Flash设备 (flash0) // 内核spi-nor驱动自动处理 // 通过mtd子系统访问 12. SPI ADC设备 (adc1) struct regulator *vcc devm_regulator_get(dev, vcc); // vcc-supply struct gpio_desc *irq_gpio devm_gpiod_get(dev, irq, GPIOD_IN); // 或 int irq platform_get_irq(pdev, 0); // 来自interrupts属性 13. PWM控制器 (pwm50004000) struct clk *pwm_clk devm_clk_get(dev, pwm); // 如果有时钟 // PWM驱动注册PWM芯片 pwmchip_add(pwm_chip); // 在consumer端 struct pwm_device *pwm devm_pwm_get(dev, NULL); // 获取第一个PWM 14. UART控制器 (serial50005000) // 驱动获取serial50005000节点 struct clk *uart_clk devm_clk_get(dev, uart); struct resource *res platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq platform_get_irq(pdev, 0); // Pinctrl获取 struct pinctrl *active devm_pinctrl_get_select(dev, default); struct pinctrl *sleep devm_pinctrl_get_select(dev, sleep); 15. DMA控制器 (dma50006000) // 获取中断 int irq platform_get_irq(pdev, 0); // 注册DMA设备 dma_async_device_register(dma_dev); // Consumer端 struct dma_chan *chan dma_request_chan(dev, tx); // 使用dma-names 16. ADC控制器 (adc50007000) // 关键vref-supply属性 → vref参数 struct regulator *vref devm_regulator_get(dev, vref); // 见下文详细解释 struct clk *adc_clk devm_clk_get(dev, adc); struct clk *vref_clk devm_clk_get(dev, vref); // 第二个时钟 // IIO框架注册 iio_device_register(indio_dev); // Consumer端 struct iio_channel *chan iio_channel_get(dev, channel0); 17. USB控制器 (usb50008000) // 多时钟获取 struct clk *otg_clk devm_clk_get(dev, otg); struct clk *phy_clk devm_clk_get(dev, phy); // PHY获取 struct phy *phy devm_phy_get(dev, usb2-phy); // phy-names匹配 // dr_mode属性读取 const char *dr_mode of_property_read_string(np, dr_mode, host); 18. Ethernet控制器 (eth50009000) // 时钟 struct clk *eth_clk devm_clk_get(dev, stmmaceth); struct clk *ptp_clk devm_clk_get(dev, ptp_ref); // PHY连接 struct device_node *phy_node of_parse_phandle(np, phy-handle, 0); phy of_phy_connect(dev, phy_node, ...); // GPIO复位关键 struct gpio_desc *reset_gpio devm_gpiod_get(dev, reset, GPIOD_OUT_LOW); // 属性名snps,reset-gpio → 参数reset用逗号前的标签 // 复位时序 snps,reset-delays-us 0 10000 10000; // 断言时间, 延迟时间, 恢复时间 of_property_read_u32_array(np, snps,reset-delays-us, delays, 3); 19. 触摸屏 (touch5000a000) struct regulator *vdd devm_regulator_get(dev, vdd); // 来自vdd-supply struct gpio_desc *reset_gpio devm_gpiod_get(dev, reset, GPIOD_OUT_LOW); // 注意irq-gpio属性 struct gpio_desc *irq_gpio devm_gpiod_get(dev, irq, GPIOD_IN); int irq gpiod_to_irq(irq_gpio); 20. 显示控制器 (display50007000) // 多regulator支持 struct regulator *vcc devm_regulator_get(dev, vcc); struct regulator *iovcc devm_regulator_get(dev, iovcc); // iovcc-supply // Endpoint连接 struct device_node *ep of_graph_get_endpoint_by_regs(np, 0, 0); struct device_node *remote of_graph_get_remote_port(ep); 21. 背光 (backlight) // PWM获取 struct pwm_device *pwm devm_pwm_get(dev, NULL); // 第一个PWM // GPIO使能 struct gpio_desc *enable_gpio devm_gpiod_get(dev, enable, GPIOD_OUT_HIGH); // 亮度表 of_property_read_u32_array(np, brightness-levels, levels, count); 22. 复位控制器 (reset-controller5000c000) // Consumer端 struct reset_control *rst devm_reset_control_get(dev, usb); reset_control_assert(rst); reset_control_deassert(rst); 24. Pinctrl (pinctrl) // 无需驱动直接访问通过pinctrl-names引用 // 获取states struct pinctrl_state *active pinctrl_lookup_state(pinctrl, default); struct pinctrl_state *sleep pinctrl_lookup_state(pinctrl, sleep);这是设备树Device Tree的节点标签Label语法用于为节点创建别名以便引用。语法分解dts复制spi0_pins_default: spi0-pins-default { /* 节点内容 */ };