第五十二讲 DTS(设备树)
第五十二讲 DTS(设备树)
一、简介
随着硬件设备的种类逐年递增,板级platform平台设备文件越来越多。在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾。
官方对设备树的描述是,一种描述硬件资源的数据结构。它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立。
设备树的主要优势:对于同一SOC的不同主板,只需更换设备树文件.dtb即可实现不同主板的无差异支持,而无需更换内核文件。
设备树结构:
设备树分类
设备树包含DTC(device tree compiler),DTS(device tree source和DTB(device tree blob)。
- DTS(device tree source):设备树源文件,ASCII格式
- DTC(device tree compiler):设备树编译工具
- DTB(device tree blob):二进制设备树
野火设备树
- 设备树由uboot负责加载到内核,内核解析使用
- 设备树源文件ebf-buster-linux/arch/arm/boot/dts/imx6ull-seeed-npi.dts(注意:这是野火pro开发板的,这里就不传上来了,csdn不能免费下载,这个文件在之前编译好的内核文件里面)
- ebf-buster-linux/arch/arm/boot/dts/imx6ull-seeed-npi.dtb(二进制设备文件,跟设备树源文件存放在同一文件下)
- /boot/dtbs/4.19.71-imx-r1/imx6ull-seeed-npi.dtb(将内核文件的二进制设备文件复制到开发板这个文件下,uboot就可以加载设备树了)
设备树编译
内核编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig
会生成一个config文件,记录了内核的详细配置信息
编译dts
make ARCH=arm -j1 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
生成dtb文件,如果之前没有编译,这里会生成多个文件
手工编译(手动调用Linux内核的工具)
将dts编译为dtb
./ scripts/dtc/dtc -I dts -O dtb -o xxx.dtb arch/arm/boot/dts/xxx.dts
将dtb反编译为dts
./scripts/dtc/dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/xxx.dtb
二、编写设备树
头文件包含
#include <dt-bindings/input/input.h>
/*
这个文件存放的是一些常用的设备树
如果需要使用
可以直接包含这个文件
*/
#include "imx6ull.dtsi"
节点命名
方法1基本方法
node-name@unit-address
{
属性1=。。。
属性2=。。。
子节点。。。
}
node-name:指定节点名称
unit-address:指定“单元地址”
方法2节点标签
cpu0:cpu@0
{
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
}
与上一个的区别就是cpu0:,这就相当于给节点名称重新再取一个“昵称”,以后可以通过这个“昵称”去叫这个节点了
方法3别名子节点
aliases
{
can0=&flexcan1;
can1=&flexcan2;
ethernet0=&fec1;
ethernet1=&fec2;
...
}
批量为其他子节点取别名
常见节点属性
属性 | 值类型 | 使用方法 | 作用 |
---|---|---|---|
compatible | 字符串 |
compatible = “manufacturer ,model” manufacturer :厂商 model:模块对应驱动的名字 例子:compatible = “arm,cortex-at-gic” |
compatible 属性的值是一个字符串列表, compatible 属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序。 |
model | 字符串 | model=“embedfire i.MX6 ULL NPi Board” | 描述板子的型号或者芯片型号 |
status | 字符串 |
okay:设备正常运行 disable:该设备尚未运行,但是在未来可以变为可操作的,比如热插拔设备插入以后。至于 disabled 的具体含义还要看设备的绑定文档。 fail:表明设备不可操作,设备检测到了一系列的错误,而且设备也不大可能变得可操作。 fail-sss:含义和“fail”相同,后面的 sss 部分是检测到的错误内容。 |
描述设备的状态信息 |
reg | 一系列(地址长度)对 | reg = <>0x02000000 0x4000>; | reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息 |
#address-cells | u32 |
soc { #address-cells = <1>; #size-cells = <1>; compatible = “simple-bus”; interrupt-parent = <&gpc>; ranges; ocrams: sram@900000 { compatible = “fsl,lpm-sram”; reg = <0x900000 0x4000>; }; }; |
决定了子节点 reg 属性中地址信息所占用的字长(32 位) |
#size-cells | u32 | 同上 | 决定了子节点 reg 属性中长度信息所占用的字长(32 位) |
ranges | ranges 是一个地址映射/转换表 | soc { #address-cells = <1>; #size-cells = <1>; compatible = “simple-bus”; interrupt-parent = <&gpc>; ranges; } |
ranges属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字矩阵, ranges 是一个地址映射/转换表, ranges 属性每个项目由子地址、父地址和地址空间长度这三部分组成:
child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells 确定此物理地址所占用的字长。 parent-bus-address: 父总线地址空间的物理地址,同样由父节点的#address-cells 确定此物理地址所占用的字长。 length: 子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。 如果 ranges 属性值为空值,说明子地址空间和父地址空间完全相同,不需要进行地址转换,对于我们所使用的 I.MX6ULL 来说,子地址空间和父地址空间完全相同,因此会在 imx6ull.dtsi中找到大量的值为空的 ranges 属性 |
name | 字符串 | name 属性用于记录节点名字, name 属性已经被弃用,不推荐使用name 属性,一些老的设备树文件可能会使用此属性 | |
device_type | 字符串 |
imx6ull.dtsi 的 cpu0 节点用到了此属性 cpu0: cpu@0 { compatible = “arm,cortex-a7”; device_type = “cpu”; reg = <0>; … }; |
IEEE 1275 会用到此属性,用于描述设备的 FCode,但是设备树没有 FCode,所以此属性也被抛弃了。此属性只能用于 cpu 节点或者 memory 节点 |
设备树示例
文件路径/sys/firmware/devicetree/base
可以通过cat
命令查看文件内容,对比野火设备树源文件
注意:视频中找的文件是imx6ull-seeed-npi.dts
,但是我在下载下来的内核里面并没有找到这个文件,不过不影响实验。在4.19.35这个内核里面对应的文件是imx6ull-mmc-npi.dts
。不过并不影响接下来的实验。
实验步骤
找到文件
imx6ull-mmc-npi.dts
路径是
ebf_linux_kernel/arch/arm/boot/dts/imx6ull-mmc-npi.dts
在文件内加入以下代码(暂时可以不懂具体干啥的,不过看参考文档你也会知道是做什么的)
test_led{#address-cells = <1>;#size-cells = <1>;rgb_led_red@0x0209C000{compatible = "fire,rgb_led_red";reg = <0x0209C000 0x00000020>;status = "okay";};};
再参考资料下面会放出整个文件内容
编译设备树(这里电脑太差了 没用多个线程编译)
make ARCH=arm -j1 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
将编译好的文件复制到共享文件目录
cp arch/arm/boot/dts/imx6ull-mmc-npi.dtb ../../nfsshare/
打开开发板并且登陆
使用nfs连接共享目录
转移到dtb目录(这里我的dtb目录也不同于视频中的,所以根据自己的实际情况做这个实验)
cd /usr/lib/linux-image-4.19.35-imx6/
将原有的dtb文件备份(为了实验完成恢复原有的dtb文件)
sudo cp imx6ull-mmc-npi.dtb imx6ull-mmc-npi.dtbback
将共享文件夹内dtb文件复制到开发板dtb目录下,并覆盖掉原始文件
sudo cp /mnt/imx6ull-mmc-npi.dtb usr/lib/linux-image-4.19.35-imx6/
重启开发板
sudo reboot
登陆开发板
查看设备树文件
ls /sys/firmware/devicetree/base/
试验成功!!!记得恢复现场呀!!
参考资料列表:
知乎
CSDN
属性资料
/** Copyright (C) 2016 Freescale Semiconductor, Inc.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*//dts-v1/;#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"/ {model = "Embedfire i.MX6ULL Board";compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";aliases {pwm0 = &pwm1;pwm1 = &pwm2;pwm2 = &pwm3;pwm3 = &pwm4;};chosen {stdout-path = &uart1;};memory {reg = <0x80000000 0x20000000>;};reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;linux,cma {compatible = "shared-dma-pool";reusable;size = <0x14000000>;linux,cma-default;};};regulators {compatible = "simple-bus";#address-cells = <1>;#size-cells = <0>;reg_sd1_vmmc: regulator@1 {compatible = "regulator-fixed";regulator-name = "VSD_3V3";regulator-min-microvolt = <3300000>;regulator-max-microvolt = <3300000>;gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;off-on-delay = <20000>;enable-active-high;};
/*reg_gpio_dvfs: regulator-gpio {compatible = "regulator-gpio";pinctrl-names = "default";pinctrl-0 = <&pinctrl_dvfs>;regulator-min-microvolt = <1300000>;regulator-max-microvolt = <1400000>;regulator-name = "gpio_dvfs";regulator-type = "voltage";gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;states = <1300000 0x1 1400000 0x0>;};
*/};leds {compatible = "gpio-leds";pinctrl-names = "default";pinctrl-0 = <&pinctrl_led>;led0: cpu {label = "cpu";gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;default-state = "on";linux,default-trigger = "heartbeat";};};/* External sound card */sound: sound {status = "disabled";};spi4: 74hc595 {compatible = "spi-gpio";pinctrl-names = "default";pinctrl-0 = <&pinctrl_spi4>;pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;status = "disabled";gpio-sck = <&gpio5 11 0>;gpio-mosi = <&gpio5 10 0>;cs-gpios = <&gpio5 7 0>;num-chipselects = <1>;#address-cells = <1>;#size-cells = <0>;gpio_spi: gpio_spi@0 {compatible = "fairchild,74hc595";gpio-controller;#gpio-cells = <2>;reg = <0>;registers-number = <1>;registers-default = /bits/ 8 <0x57>;spi-max-frequency = <100000>;};};test_led{#address-cells = <1>;#size-cells = <1>;rgb_led_red@0x0209C000{compatible = "fire,rgb_led_red";reg = <0x0209C000 0x00000020>;status = "okay";};};
};&cpu0 {/*dc-supply = <®_gpio_dvfs>;*/clock-frequency = <800000000>;
};&clks {assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;assigned-clock-rates = <786432000>;
};&fec1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet1>;phy-mode = "rmii";phy-handle = <ðphy0>;status = "okay";
};&fec2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet2>;phy-mode = "rmii";phy-handle = <ðphy1>;status = "okay";mdio {#address-cells = <1>;#size-cells = <0>;ethphy0: ethernet-phy@2 {compatible = "ethernet-phy-ieee802.3-c22";reg = <2>;micrel,led-mode = <1>;clocks = <&clks IMX6UL_CLK_ENET_REF>;clock-names = "rmii-ref";};ethphy1: ethernet-phy@1 {compatible = "ethernet-phy-ieee802.3-c22";reg = <1>;micrel,led-mode = <1>;clocks = <&clks IMX6UL_CLK_ENET2_REF>;clock-names = "rmii-ref";};};
};&gpc {fsl,cpu_pupscr_sw2iso = <0xf>;fsl,cpu_pupscr_sw = <0x0>;fsl,cpu_pdnscr_iso2sw = <0x1>;fsl,cpu_pdnscr_iso = <0x1>;fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
};&iomuxc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_hog_1>;pinctrl_hog_1: hoggrp-1 {fsl,pins = <MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */>;};pinctrl_enet1: enet1grp {fsl,pins = <MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031>;};pinctrl_enet2: enet2grp {fsl,pins = <MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031>;};pinctrl_uart1: uart1grp {fsl,pins = <MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1>;};/*pinctrl_dvfs: dvfsgrp {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79>;};
*/pinctrl_usdhc1: usdhc1grp {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059>;};pinctrl_usdhc1_100mhz: usdhc1grp100mhz {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9>;};pinctrl_usdhc1_200mhz: usdhc1grp200mhz {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9>;};pinctrl_usdhc2: usdhc2grp {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059>;};pinctrl_usdhc2_8bit: usdhc2grp_8bit {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059>;};pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9>;};pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9>;};pinctrl_led: ledgrp {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x1b0b0>;};
};&iomuxc_snvs {pinctrl-names = "default_snvs";pinctrl-0 = <&pinctrl_hog_2>;pinctrl_hog_2: hoggrp-2 {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000>;};pinctrl_spi4: spi4grp {fsl,pins = <MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000>;};
};&snvs_pwrkey {status = "okay";
};&pxp {status = "okay";
};&uart1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_uart1>;status = "okay";
};&usbotg1 {dr_mode = "otg";srp-disable;hnp-disable;adp-disable;status = "okay";
};&usbotg2 {dr_mode = "host";disable-over-current;status = "okay";
};&usbphy1 {fsl,tx-d-cal = <106>;
};&usbphy2 {fsl,tx-d-cal = <106>;
};&usdhc1 {pinctrl-names = "default", "state_100mhz", "state_200mhz";pinctrl-0 = <&pinctrl_usdhc1>;pinctrl-1 = <&pinctrl_usdhc1_100mhz>;pinctrl-2 = <&pinctrl_usdhc1_200mhz>;no-1-8-v;/*cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;*/keep-power-in-suspend;/*non-removable;*/enable-sdio-wakeup;vmmc-supply = <®_sd1_vmmc>;status = "okay";
};&usdhc2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_usdhc2_8bit>;non-removable;status = "okay";
};
rent;
status = “okay”;
};
&usbphy1 {
fsl,tx-d-cal = <106>;
};
&usbphy2 {
fsl,tx-d-cal = <106>;
};
&usdhc1 {
pinctrl-names = “default”, “state_100mhz”, “state_200mhz”;
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
no-1-8-v;
/cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;/
keep-power-in-suspend;
/non-removable;/
enable-sdio-wakeup;
vmmc-supply = <®_sd1_vmmc>;
status = “okay”;
};
&usdhc2 {
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
non-removable;
status = “okay”;
};
第五十二讲 DTS(设备树)相关推荐
- 高通平台msm8953 Linux DTS(Device Tree Source)设备树详解之二(DTS设备树匹配过程)
本系列导航: 高通平台8953 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) 高通平台8953 Linux DTS(Device Tree Source ...
- 【genius_platform软件平台开发】第五十二讲:Linux系统之V4L2视频驱动详解
V4L2视频驱动详解 刚建的微信群欢迎加入一起学习.讨论: 1. 简介 1.1 视频输入输出设备(video capture device,video output device) 1.2 VBI设备 ...
- 线性代数学习笔记——第五十二讲——齐次方程组解的性质和基础解系
1. 齐次方程组的平凡解及有非零解的等价命题(矩阵非满秩:矩阵列向量组线性相关) 2. 齐次线性方程组解的性质(两解之和.解的数乘.解的线性组合均是解) 3. 齐次线性方程组的全部解构成的集合中包括零 ...
- 如何选择适合你的兴趣爱好(五十二),泥人
围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第五十二讲--泥人.泥人是以泥巴陶土为主料,调成不同色彩,用手和简单工具,塑造各种栩栩如生的形象.由于它的色彩丰富 ...
- 第五十四讲 设备树实现RGB驱动
第五十四讲 设备树实现RGB驱动 文章目录 第五十四讲 设备树实现RGB驱动 一.基础知识 1.GPIO Write Mode 2.硬件连接 3.重要寄存器(参考IMXULL用户手册) RGB_R R ...
- 第五十六讲 pinctrl子系统
第五十六讲 pinctrl子系统 文章目录 第五十六讲 pinctrl子系统 一.前言 二.iomuxc 节点 1.作用 2.节点信息 3.节点格式 4.引脚配置信息 三.imx_pinctrl和pi ...
- 动画骨骼【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)...
间时紧张,先记一笔,后续优化与完善. 本系列文章由zhmxy555(毛星云)编写,载转请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/detail ...
- 【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)
这是答应大家的讲解骨骼动画的文章的N部曲的第二篇.这篇文章里,我们对现行的三种模型动画技术进行了概述,然后对X文件构成进行了详细的剖析,最后放出了骨骼动画的第一个示例程序,载入了<诛仙>中 ...
- 【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8832812 作者:毛星云(浅墨 ...
最新文章
- SEO优化技巧之Alt标签的使用方法
- GloVe:Global Vectors for Word Representation
- CH - 0802 占卜DIY(简单模拟,水题)
- probability space 概率空间,Filtration,σ-algebras
- 雷人!09年0分最具文采的高考作文
- Salesforce 超越 Oracle:四十年的甲骨文和二十岁的SaaS之王
- 现任明教教主vsphere视频共享部分新共享连接
- 突然挂了!Redis 缓存都在内存中,这下完了!
- 度量相似性数学建模_数学之美读书笔记
- Ubuntu系统下面软件安装更新命令
- 5个好用的样机素材网站
- 你真的了解LinkedBlockingQueue的put,add和offer的区别吗
- springboot设置局域网访问
- 一文带你轻松掌握多种编程范式
- 微信机器人服务器成本,微信机器人案例汇总
- Vue:v-charts图表设置指标别名
- 分治法 逆序对计数 O(nlgn)
- [GKCTF2020]EZ三剑客-EzWeb
- 时序数据库:TimescaleDB的安装
- CFLOW-AD:通过条件归一化流量进行实时无监督的异常检测与定位