openwrt DTS介紹


1、概述

  DTS是Device Tree Source的縮寫,用來描述設備的硬件細節。在過去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代碼,相當多數的代碼只是在描述板級細節,而這些板級細節對於內核來講,不過是垃圾,如板上的platform設備、resource、i2c_board_info、spi_board_info以及各種硬件的platform_data。為了去掉這些垃圾代碼,Linux采用DTS這種新的數據結構來描述硬件設備。采用Device Tree后,許多硬件的細節可以直接透過它傳遞給Linux,而不再需要在kernel中進行大量的冗余編碼。

2、DTS節點解析

Linux在啟動后,到C入口時,會執行以下操作,加載系統平台上的總線和設備:

start_kernel() --> setup_arch() --> unflatten_device_tree() 

unflatten_device_tree()的代碼如下:

void __init unflatten_device_tree(void)  
{  
    __unflatten_device_tree(initial_boot_params, &allnodes,  
                early_init_dt_alloc_memory_arch);  
  
    /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */  
    of_alias_scan(early_init_dt_alloc_memory_arch);  
} 

在執行完unflatten_device_tree()后,DTS節點信息被解析出來,保存到allnodes鏈表中,allnodes會在后面被用到。

  隨后,當系統啟動到board文件時,會調用.init_machine,高通8974平台對應的是msm8974_init()。接着調用of_platform_populate(....)接口,加載平台總線和平台設備。至此,系統平台上的所有已配置的總線和設備將被注冊到系統中。注意:不是dtsi文件中所有的節點都會被注冊,在注冊總線和設備時,會對dts節點的狀態作一個判斷,如果節點里面的status屬性沒有被定義或者status屬性被定義了並且值被設為“ok”或者“okay”,其他情況則不被注冊到系統中

//例如:dts文件定義led GPIO的結構對象
	leds {
 		compatible = "gpio-leds";
 
 		pwr_led {
 			label = "green:pwr";
 			gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
 		};
 
 		status_led {
 			label = "red:status";
 			gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
			default-state = "on";
 		};
 	};

LED device注冊后,會在/sys/devices/platform/leds-gpio/目錄中,產生對應的led燈的控制目錄:(紅燈和綠燈)

 

 

 

 

 通過 echo 1 > brightness,就可以控制燈亮; echo 0 > brightness,就可以控制燈滅 。

//openwrt/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-sunxi_cortexa7/linux-4.14.25/drivers/leds/leds-gpio.c

leds-gpio.c驅動文件會定義了對於led燈的操作:

static inline struct gpio_led_data *
			cdev_to_gpio_led_data(struct led_classdev *led_cdev)

static void gpio_led_set(struct led_classdev *led_cdev,
	enum led_brightness value)

static int gpio_led_set_blocking(struct led_classdev *led_cdev,
	enum led_brightness value)

static int gpio_blink_set(struct led_classdev *led_cdev,
	unsigned long *delay_on, unsigned long *delay_off)

static int create_gpio_led(const struct gpio_led *template,
	struct gpio_led_data *led_dat, struct device *parent,
	struct device_node *np, gpio_blink_set_t blink_set)

static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
static int gpio_led_probe(struct platform_device *pdev)
static void gpio_led_shutdown(struct platform_device *pdev)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM