第五十二讲 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):二进制设备树

野火设备树

  1. 设备树由uboot负责加载到内核,内核解析使用
  2. 设备树源文件ebf-buster-linux/arch/arm/boot/dts/imx6ull-seeed-npi.dts(注意:这是野火pro开发板的,这里就不传上来了,csdn不能免费下载,这个文件在之前编译好的内核文件里面)
  3. ebf-buster-linux/arch/arm/boot/dts/imx6ull-seeed-npi.dtb(二进制设备文件,跟设备树源文件存放在同一文件下)
  4. /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。不过并不影响接下来的实验。

实验步骤

  1. 找到文件imx6ull-mmc-npi.dts

    路径是ebf_linux_kernel/arch/arm/boot/dts/imx6ull-mmc-npi.dts

  2. 在文件内加入以下代码(暂时可以不懂具体干啥的,不过看参考文档你也会知道是做什么的)

    test_led{#address-cells = <1>;#size-cells = <1>;rgb_led_red@0x0209C000{compatible = "fire,rgb_led_red";reg = <0x0209C000 0x00000020>;status = "okay";};};
    

    再参考资料下面会放出整个文件内容

  3. 编译设备树(这里电脑太差了 没用多个线程编译)

    make ARCH=arm -j1 CROSS_COMPILE=arm-linux-gnueabihf- dtbs

  4. 将编译好的文件复制到共享文件目录

    cp arch/arm/boot/dts/imx6ull-mmc-npi.dtb ../../nfsshare/

  5. 打开开发板并且登陆

  6. 使用nfs连接共享目录

  7. 转移到dtb目录(这里我的dtb目录也不同于视频中的,所以根据自己的实际情况做这个实验)

    cd /usr/lib/linux-image-4.19.35-imx6/

  8. 将原有的dtb文件备份(为了实验完成恢复原有的dtb文件)

    sudo cp imx6ull-mmc-npi.dtb imx6ull-mmc-npi.dtbback

  9. 将共享文件夹内dtb文件复制到开发板dtb目录下,并覆盖掉原始文件

    sudo cp /mnt/imx6ull-mmc-npi.dtb usr/lib/linux-image-4.19.35-imx6/

  10. 重启开发板

    sudo reboot

  11. 登陆开发板

  12. 查看设备树文件

    ls /sys/firmware/devicetree/base/

  13. 试验成功!!!记得恢复现场呀!!

参考资料列表:

知乎

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 = <&reg_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 = <&ethphy0>;status = "okay";
};&fec2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet2>;phy-mode = "rmii";phy-handle = <&ethphy1>;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 = <&reg_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 = <&reg_sd1_vmmc>;
status = “okay”;
};

&usdhc2 {
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
non-removable;
status = “okay”;
};

第五十二讲 DTS(设备树)相关推荐

  1. 高通平台msm8953 Linux DTS(Device Tree Source)设备树详解之二(DTS设备树匹配过程)

    本系列导航: 高通平台8953  Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) 高通平台8953 Linux DTS(Device Tree Source ...

  2. 【genius_platform软件平台开发】第五十二讲:Linux系统之V4L2视频驱动详解

    V4L2视频驱动详解 刚建的微信群欢迎加入一起学习.讨论: 1. 简介 1.1 视频输入输出设备(video capture device,video output device) 1.2 VBI设备 ...

  3. 线性代数学习笔记——第五十二讲——齐次方程组解的性质和基础解系

    1. 齐次方程组的平凡解及有非零解的等价命题(矩阵非满秩:矩阵列向量组线性相关) 2. 齐次线性方程组解的性质(两解之和.解的数乘.解的线性组合均是解) 3. 齐次线性方程组的全部解构成的集合中包括零 ...

  4. 如何选择适合你的兴趣爱好(五十二),泥人

    围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第五十二讲--泥人.泥人是以泥巴陶土为主料,调成不同色彩,用手和简单工具,塑造各种栩栩如生的形象.由于它的色彩丰富 ...

  5. 第五十四讲 设备树实现RGB驱动

    第五十四讲 设备树实现RGB驱动 文章目录 第五十四讲 设备树实现RGB驱动 一.基础知识 1.GPIO Write Mode 2.硬件连接 3.重要寄存器(参考IMXULL用户手册) RGB_R R ...

  6. 第五十六讲 pinctrl子系统

    第五十六讲 pinctrl子系统 文章目录 第五十六讲 pinctrl子系统 一.前言 二.iomuxc 节点 1.作用 2.节点信息 3.节点格式 4.引脚配置信息 三.imx_pinctrl和pi ...

  7. 动画骨骼【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)...

    间时紧张,先记一笔,后续优化与完善. 本系列文章由zhmxy555(毛星云)编写,载转请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/detail ...

  8. 【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)

    这是答应大家的讲解骨骼动画的文章的N部曲的第二篇.这篇文章里,我们对现行的三种模型动画技术进行了概述,然后对X文件构成进行了详细的剖析,最后放出了骨骼动画的第一个示例程序,载入了<诛仙>中 ...

  9. 【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8832812 作者:毛星云(浅墨 ...

最新文章

  1. SEO优化技巧之Alt标签的使用方法
  2. GloVe:Global Vectors for Word Representation
  3. CH - 0802 占卜DIY(简单模拟,水题)
  4. probability space 概率空间,Filtration,σ-algebras
  5. 雷人!09年0分最具文采的高考作文
  6. Salesforce 超越 Oracle:四十年的甲骨文和二十岁的SaaS之王
  7. 现任明教教主vsphere视频共享部分新共享连接
  8. 突然挂了!Redis 缓存都在内存中,这下完了!
  9. 度量相似性数学建模_数学之美读书笔记
  10. Ubuntu系统下面软件安装更新命令
  11. 5个好用的样机素材网站
  12. 你真的了解LinkedBlockingQueue的put,add和offer的区别吗
  13. springboot设置局域网访问
  14. 一文带你轻松掌握多种编程范式
  15. 微信机器人服务器成本,微信机器人案例汇总
  16. Vue:v-charts图表设置指标别名
  17. 分治法 逆序对计数 O(nlgn)
  18. [GKCTF2020]EZ三剑客-EzWeb
  19. 时序数据库:TimescaleDB的安装
  20. CFLOW-AD:通过条件归一化流量进行实时无监督的异常检测与定位

热门文章

  1. 使用layer弹出层组件绑定页面按钮
  2. PHP设计模式 - 门面模式(Facade)通俗易懂 / 友好示例代码
  3. 古人说过自相矛盾的话
  4. 程序员的乐趣是什么?
  5. 【003】中国主要城市交通健康榜-实时获取城市拥堵数据
  6. java如何记录方法运行时间?
  7. 计算机义讲活动总结,计算机社团活动总结.pdf
  8. ArcGIS二次开发知识点总结
  9. GitHub托管BootStrap资源汇总
  10. 用java编写的爱情红心_如何用java实现每天给对象发情话