当前位置: 首页 > news >正文

永久免费国外ip代理/宁波网站推广优化哪家正规

永久免费国外ip代理,宁波网站推广优化哪家正规,深圳高端网站建设费用,做网站方案一、什么是设备树 1、新版本的 linux 中,ARM 相关的驱动全部采用了设备树,最新出的 CPU 的驱动开发基本都是基于设备树的2、uboot 启动内核用到 zImage 、imx6ull-alientek-emmc.dtb 。bootz 80800000 - 830000003、设备树 就是 设备 和 树,…

一、什么是设备树

  • 1、新版本的 linux 中,ARM 相关的驱动全部采用了设备树,最新出的 CPU 的驱动开发基本都是基于设备树的
  • 2、uboot 启动内核用到 zImageimx6ull-alientek-emmc.dtbbootz 80800000 - 83000000
  • 3、设备树 就是 设备,描述设备树的文件叫做 DTS,DTS 采用树形结构描述板级设备信息。
    在这里插入图片描述
    主干是系统总线,主干的分支是控制器,分支的分支上接的是具体的设备
  • 4、在单片机驱动 里面,spi flash芯片:w25q64 的速度属性都是在 .c 文件中写死的。
    若板级信息都写到 .c 里面会产生大量的 .c 文件。把不同的板子信息以这样的形式都写到内核里显然不现实。
    因此将板子信息做成独立的格式,文件后缀为 .dts。一个平台会者机器对应一个 .dts

二、DTS、DTB 和 DTC 的关系

  • .dts :相当于 .c 文件,将板级信息从linux内核中分离出来,用此种格式来描述,就是设备树源码文件
  • .dtsi :相当于 .h 文件,一款SOC可以做出很多种板子,这些不同的板子必然有共同的信息,将这些信息提取出来做为有一个通用的文件,其它的 .dts文件直接引用这个 .dtsi文件即可(一般 .dts 描述板级信息( 也就是开发板上有哪些 IIC 设备、 SPI 设备等 ), .dtsi 描述 SOC 级信息(比如 CPU 架构、主频、外设寄存器地址范围,比如 UART、 IIC 等等。比如 imx6ull.dtsi 就是描述 I.MX6ULL 这颗 SOC 内部外设情况信息的 )
  • DTC 工具就相当于gcc编译器,将 .dts 编译成 .dtb 文件
  • .dtb 文件相当于 bin文件 或者 可执行文件,可由 DTC 工具将 .dts 编译成 .dtb 文件, DTC 源码在 Linux 内核的 scripts/dtc 目录下
  • 描述板级硬件信息的内容都从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文件就叫做设备树,文件扩展名为.dts。 一个 SOC 可以作出很多不同的板子,这些不同的板子肯定是有共同的信息, 将这些共同的信息提取出来作为一个通用的文件,其他的.dts 文件直接引用这个通用文件即可,这个通用文件就是.dtsi 文件,类似于 C 语言中的头文件。一般.dts 描述板级信息(也就是开发板上有哪些 IIC 设备、 SPI 设备等), .dtsi 描述 SOC 级信息(也就是 SOC 有几个 CPU、主频是多少、各个外设控制器信息等)
  • 通过 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs 编译所有的 dts文件,若要编译指定的 .dts

三、DTS基本语法

  • 1、设备树文件也就是 dts文件 也有头文件,扩展名为 .dtsi。可以将一款SOC的其它所有设备 / 平台的共有的信息提出来,作为一个通用的 .dtsi 文件,.dtsi 文件一般是用来描述cpu内部外设的属性的。(.dts 还可以包含 c 的头文件)
  • 2、DTS也是以 / 开始。
    dts文件的注释方法同c。
/dts-v1/;#include <dt-bindings/input/input.h> 			// 可以包含c的头文件
#include "imx6ull.dtsi"		// 设备树头文件 / { 					// 斜杠后面这个括号表示根结点// skeleton.dtsi文件(3者的)的根结点合并到一起#address-cells = <1>;#size-cells = <1>;chosen {  //处理同memorystdout-path = &uart1;};aliases { // skeleton.dtsi文件中有此一级子节点但是空的,imx6ull.dtsi也有此节点,将节点内的内容移动到此处,如下can0 = &flexcan1;...};memory { device_type = "memory"; //reg = <0 0>; 下面也有个memory一级子节点,此种情况下的处理方法是合并同类项,同样的reg,保留后面的。所以欲修改某个属性值可以在后面再赋值一次即可reg = <0x80000000 0x20000000>;  //(起始地址和长度)};cpus {};intc: interrupt-controller@00a01000 {};// 描述 6ull 芯片内部内存映射,内部外设信息clocks {};soc {...aips2: aips-bus@02100000 {compatible = "fsl,aips-bus", "simple-bus";#address-cells = <1>;#size-cells = <1>;reg = <0x02100000 0x100000>;ranges;usbotg1: usb@02184000 {};usbotg2: usb@02184200 {};usbmisc: usbmisc@02184800 {};fec1: ethernet@02188000 {};...i2c1: i2c@021a0000 {// imx6ull.dtsi 里的 i2c1 属性信息只有这么多,通用信息或属性,半导体厂商做好的#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021a0000 0x4000>;interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C1>;// status = "disabled"; 默认是 disable,在下面改为 okay,此处屏蔽// imx6ull-alientek-emmc.dts 追加的部分如下clock-frequency = <100000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_i2c1>;status = "okay";// 具体的 i2c 设备,磁力计,0e表示设备地址mag3110@0e {compatible = "fsl,mag3110";reg = <0x0e>;position = <2>;};// 具体的 i2c 设备,6轴传感器fxls8471@1e {compatible = "fsl,fxls8471";reg = <0x1e>;position = <0>;interrupt-parent = <&gpio5>;interrupts = <0 8>;};}; // i2c1...}; // aips2...}; // socmodel = "string"; 		// (属性名 = 属性值)compatible = "string"chosen { 				 //(一级子节点,他自己没有子节点了,若有其就是二级子节点)stdout-path = &uart1;};memory {				 //(一级子节点)reg = <0x80000000 0x20000000>;  //(起始地址和长度)};reserved-memory {};backlight {};pxp_v4l2 {};regulators {};sound {};spi4 {};
};
  • 3、从根节点开始描述设备信息
  • 4、在 根节点外有一些取址符号如 &cpu0 这样的语句是追加
  • 5、节点名字的完整要求:node_name@unit_address
    有时也常常会遇到这种格式 label: node-name@unit-address,label 是节点标签,后面的才是节点名字,引入 label 的目的就是为了方便访问节点,可以直接通过 &label 来访问这个节点,比如通过 &cpu0 就可以访问“cpu@0”这个节点,而不需要输入完整的节点名字。.dts 文件中有使用此方法来访问 .dtsi 文件中定义的节点的 &lcdif ,注意只有标签后面才能接 冒号: ,节点名称后面直接 空格,大括号。而且追加访问只能在根结点同一级处里面追加,不能在一级子节点、二级子节点中追加访问
    在这里插入图片描述
    unit_address 一般都是外设寄存器的起始地址(不绝对),有时候是 I2C 的设备地址或者其它含义,具体节点具体分析
    例如:
i2c4: i2c@021f8000 { // 021f8000是单元起始地址#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021f8000 0x4000>;interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C4>;status = "disabled";};
uart6: serial@021fc000 {compatible = "fsl,imx6ul-uart","fsl,imx6q-uart", "fsl,imx21-uart";reg = <0x021fc000 0x4000>;interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_UART6_IPG>,<&clks IMX6UL_CLK_UART6_SERIAL>;clock-names = "ipg", "per";dmas = <&sdma 0 4 0>, <&sdma 47 4 0>;dma-names = "rx", "tx";status = "disabled";};

五、设备树在系统中的体现

  • 使用指令 ls /proc/device-tree
  • 设备启动以后可以在根文件系统中看到设备树的节点信息。
    /proc/device-tree 目录下存放的是设备树中 根节点的各个一级子节点,这些 一级子节点 是以 目录 的形式给出的
    分别进入这些代表着 一级子节点的目录,里面的文件表示这些一级子节点的各个属性
/sys/firmware/devicetree/base # ls
#address-cells                 memory
#size-cells                    model
aliases                        name
backlight                      pxp_v4l2
chosen                         regulators
clocks                         reserved-memory
compatible                     soc
cpus                           sound
interrupt-controller@00a01000  spi4
/sys/firmware/devicetree/base # 
/sys/firmware/devicetree/base # 
/sys/firmware/devicetree/base # 
/sys/firmware/devicetree/base # 
  • 内核启动的时候会解析设备树,然后在 /procdevice-tree 目录下呈现出来。解析过程本次不做介绍。

六、特殊节点

  • 1、aliases

  • 2、chosen:主要是了 uboot 向 Linux 内核传递数据,重点是 bootargs 参数作为命令行参数。
    uboot里面的 bootargs 值为 bootargs=console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.77:/home/jl/linux/nfs/rootfs ip=192.168.1.66:192.168.1.77:192.168.1.1:255.255.255.0::eth0:off
    linux kernel cmdline 为 Kernel command line: console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.77:/home/jl/linux/nfs/rootfs ip=192.168.1.66:192.168.1.77:192.168.1.1:255.255.255.0::eth0:off
    一般 .dts 文件中 chosen 节点通常为空或者内容很少

  • uboot 是如何向 kernel 传递 bootargs 的?
    cd /proc/device-tree
    该目录下有三个文件:bootargs name stdout-path
    bootargs 属性值和 uboot 里面的环境变量 一样
    但是在设备树文件 imx6ull-alientek-emmc.dts 文件中,chosen 节点内只有 stdout-path 这一个
    uboot 接触过 dtb,最终通过 bootz 80800000 - 83000000 来启动内核的,经过分析判断, uboot 拥有 bootargs 环境变量和 dtb 文件,可能是 uboot 修改了 dtb,最终发现在 fdt_support.c 中的 fdt_chosen 函数中添加了这个属性值。
    在这里插入图片描述
    在这里插入图片描述

七、特殊属性

  • 脱离一个具体的器件来看设备树中结点的属性是没有意义的,此处只介绍一些约定俗成的属性(page 1082)
  • 1、compatible
    兼容性属性
    值是一个字符串列表
    用于将设备和驱动绑定起来
pxp_v4l2 {compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";status = "okay";};
...
sound {compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";  // 支持这两个设备model = "wm8960-audio";cpu-dai = <&sai2>;...
}
// 内核源码 imx-wm8960.c
static const struct of_device_id imx_wm8960_dt_ids[] = {{ .compatible = "fsl,imx-audio-wm8960", },{ /* sentinel */ }
};
  • 2、model
    model 属性值也是一个字符串,一般 model 属性描述设备模块信息,比如名字什么的
  • 3、status
    是和设备状态有关的, status 属性值也是字符串,字符串是设备的状态信息,上两个值常用
    在这里插入图片描述
  • 4、#address-cells 和#size-cells
    #address-cells 和#size-cells 这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息
    设备树中#address-cells和#size-cells作用
// 父节点的决定子节点的
i2c1: i2c@021a0000 {#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021a0000 0x4000>;interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C1>;status = "disabled";};

  • 根结点的compatible属性,值是字符串

  • 根结点下的用于内核查找,判断是否支持这个平台
    内核启动时会检查是否支持此平台或者机器(教程 1086)

  • 不使用设备树时,通过 machine id 来判断内核是否支持
    Linux内核都用 MACHINE_STARTMACHINE_END 来定义一个 machine_desc 结构体来描述这个设备

// arch.h
/* * Set of macros to define architecture features.  This is built into* a table by the linker.*/
#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\__used							\__attribute__((__section__(".arch.info.init"))) = {	\.nr		= MACH_TYPE_##_type,		\.name		= _name,#define MACHINE_END				\
};

展开示例见教程 1087,1088

  • 使用设备树的话,就不需要使用机器ID,而是使用根节点的 compatible 属性值 (教程1088 末尾开始)

八、linux内核的 OF 操作函数

  • 1、驱动如何获取到设备书中节点信息,在驱动中使用 OF函数 来获取设备树属性内容(教程 1106)
  • 2、驱动要想获取到设备树节点内容,首先要找到节点

九、源码

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include <linux/fs.h>
#include<linux/slab.h>
#include<linux/io.h>
#include<linux/uaccess.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<linux/of.h>
#include<linux/of_address.h>
#include<linux/of_irq.h>#if 0backlight {compatible = "pwm-backlight";pwms = <&pwm1 0 5000000>;brightness-levels = <0 4 8 16 32 64 128 255>;default-brightness-level = <6>;status = "okay";};
#endif// 驱动入口函数
static int __init dtsof_init(void)
{// 在调用 modprobe 时完成获取设备树int ret = 0;struct device_node *bl_nd;struct property *comppro;const char *str;u32 def_value;u32 *brival;u8 cnt = 0;u8 i = 0;// 1. 寻找节点,node:backlight// 参数为 节点的路径bl_nd = of_find_node_by_path("/backlight");if(bl_nd == NULL) // 寻找失败{printk("Fail\r\n");ret = -1;goto fail_findnd;}// 获取 backlight 结点下的 compatible 属性// 1comppro = of_find_property(bl_nd, "compatible", NULL);if(comppro == NULL){printk("Fail\r\n");ret = -1;goto failfindpro;}else{printk("compatilble = \"%s\"\r\n", (char *)comppro->value);}// 2// 获取 backlight 结点下的 status 属性ret = of_property_read_string(bl_nd, "status", &str);if(ret){goto fail_getstatus;}else{printk("status = \"%s\"\r\n", str);}//3// 获取 backlight 结点下的 default-brightness-level 属性ret = of_property_read_u32(bl_nd, "default-brightness-level", &def_value);if(ret < 0){goto fail_readu32;}else{printk("default-brightness-level = %u\r\n", def_value);}// 4// 获取 backlight 结点下的 brightness-levels 属性ret = of_property_count_elems_of_size(bl_nd, "brightness-levels", sizeof(u32));if(ret < 0){goto fail_readele;}else{cnt = ret;printk("ele_size = %d\r\n", cnt);}brival = kmalloc(ret*sizeof(u32), GFP_KERNEL);if(!brival){ret = -1;goto fail_kmalloc;}ret = of_property_read_u32_array(bl_nd, "brightness-levels", brival,cnt);if(ret < 0){goto fail_readarray;}else{printk("\"brightness-levels\" = < ");for(i=0; i<cnt; i++){printk("%d ", brival[i]);}printk(" >\r\n");kfree(brival);}return 0;fail_readarray:kfree(brival);
fail_kmalloc:
fail_readele:
fail_readu32:
fail_getstatus:
failfindpro:
fail_findnd:return ret;
}// 出口函数
static void __exit dtsof_exit(void)
{;
}
// register module entrance and exit
module_init(dtsof_init);
module_exit(dtsof_exit);
MODULE_LICENSE("GPL");

十、测试

  • 1、第一次加载 dtsof.ko 这个驱动,先试用指令 depmod
  • 2、modprobe dtsof.ko
http://www.lbrq.cn/news/1367803.html

相关文章:

  • iis默认网站路径/郑州中原区最新消息
  • 青羊区定制网站建设报价/惠州seo博客
  • 杭州网站建设及推广/百度官网推广平台
  • 网站怎么做精准引流/百度云app
  • 网站建设需要的费用/搜索引擎优化免费
  • 贵州软件开发 网站开发/竞价恶意点击报案
  • 印刷网站建设 优帮云/网络营销网站建设案例
  • 文件包上传的网站怎么做/石家庄网站建设公司
  • 营销型网站重要特点是/全网营销推广怎么做
  • 专门做校招的网站/哪个模板建站好
  • 做网站用什么语言好/外贸网站平台都有哪些
  • 营销型高端网站建设价格/网络营销与直播电商怎么样
  • 苏州党员两学一做网站/厦门人才网唯一官网招聘
  • 1.申请网站空间/在哪里可以做百度推广
  • 漳州城乡住房建设部网站/网站推广软件
  • nh网站建设/网络上如何推广网站
  • 南京做网站南京乐识专注/郑州关键词优化费用
  • 通知中心app下载/西安网络推广seo0515
  • 网站建设网站设计/百度网页游戏中心
  • 网站优化方式有哪些/如何自己做推广
  • 自己做的网站如何制作后台/国外网络推广
  • 怎么做flash网站/深圳百度首页优化
  • dw如何做网站/宁波seo推广联系方法
  • 有多少做汽车的网站/宁波seo快速排名
  • 中山做展示型网站/购物网站
  • 网站icp备案是什么/怎么做网站教程视频
  • 用div css做网站第一步/上海比较大的优化公司
  • 网站建设职位/爱站网关键词长尾挖掘
  • wordpress html代码/上海优化seo公司
  • 编程 毕业设计代做网站/win7优化大师下载
  • Linux U盘识别问题排查指南
  • 关于Web前端安全之XSS攻击防御增强方法
  • PostgreSQL面试题及详细答案120道(21-40)
  • [创业之路-535]:软件需要原型验证、产品需要原型验证、商业模式也需要原型验证
  • 力扣 hot100 Day63
  • 【Android】使用 Intent 传递对象的两种序列化方式