CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

嵌入式linux入门(一篇读懂)学嵌入式linux需要学哪些知识,嵌入式Linux设备树语法总结,

1.嵌入式一定要学linux

1 设备树的说明在写完嵌入式驱动总结后,对于设备树相关的语法和使用一直都想进行系统的描述,但是因为最近比较忙碌,所以一直拖到现在才完成初版,对于整个嵌入式Linux驱动开发中,设备树语法和构建是其中比较核心的部分,是需要比较系统的去学习掌握的。

2.linux嵌入式开发入门

本文参考设备树说明文档, 在结合日常驱动开发中积累的经验,总结完成的一篇设备树语法的说明对于驱动的编写来说,设备树语法的了解自然必不可少,但大多数情况下我们模仿厂商的实现,在结合芯片手册就可以增加自己需要的功能,不过如何来添加设备节点,保证添加的有效性,这时候就需要掌握理和解设备树语法。

3.嵌入式linux和linux

随着设备树逐渐成为嵌入式驱动开发中的主流,并逐渐取代寄存器的访问方式,设备树对于驱动开发越来越重要,另外如果在本章了解中对于设备树中有疑惑不理解的部分,这很正常,可以先大概浏览下,做到心中有着概念,在带着疑问去学习驱动的内容,当你困惑的时候,可以回来系统的理解设备树的语法(不理解不要纠结),不要在缺少积累的时候去钻牛角尖,这也是嵌入式学习的重要经验。

4.嵌入式linux应用开发详解

1.1 设备树综述对SOC构造和嵌入式硬件有了解的话,芯片一般由内核(Cortex-A), 以及通过系统总线(AHB, AXI等)挂载的GPIO,I2C,SPI,PWM,Ethernet等外设模块构成而对于具体的外设模块,如I2C外设,又支持访问多个器件来满足不同功能的需求。

5.嵌入式linux学什么

而设备树,就是基于系统总线作为主干,将芯片SOC和各类外设以及外部器件用数据结构的形式组合起来描述硬件结构的文件,是对硬件模型的抽象,总结来说,设备树就是对硬件结构的抽象描述

6.嵌入式linux知识点

上面就是比较常见的基于SOC构建的嵌入式应用系统,包含芯片和外围的设备,虽然总线可能不指一条,外设模块的设备连接情况也会更加复杂,但都没有树结构模型,而设备树也是按照如此模型进行设计的,理解这一点,也可以更深刻的知道设备树的实现思路。

7.Linux和嵌入式

在对嵌入式整个硬件框架有一定了解后,下面还要理解几个名词 DTS 设备树的源码文件,用于描述设备硬件情况的抽象 DTSI 和C语言的#include类似,也是描述设备树的源码文件,另外DTS同样被#include包含。

8.嵌入式为什么要学linux

DTB 基于DTS源码编译的二进制文件,用于内核调用读取设备树信息的文件 DTC 用于编译DTS到DTB的工具,由内核编译时使用make dtbs编译设备树二进制文件过程中生成 基于以上信息,我们理解DTS/DTSI是基于DTS语法实现的设备描述文件,DTB则是用于内核解析,需要下载的文件,下面正式开始设备树语法的讲解。

9.Linux是嵌入式

1.2 设备树语法在上一小节,我们将设备树的概念有基本的认知,下面更重要的就是DTS语法了,这里我么结合实际的代码区理解设备树语法1.2.1 #include语法DTS中#include语法和C语言中类似,支持将包裹的文件直接放置在#include位置从而访问到其它文件的数据,如官方设备树内使用的。

10.嵌入式linux需要学什么

#include#include”imx6ull.dtsi”另外,也可以用来包含dts文件,如下#include “imx6ull-14×14-evk.dts”

1.2.2 节点描述对于设备树来说,都是有根节点开始,在添加不同的设备节点描述的,以比较简单的LED设备树为例:/{//根节点//……led{//节点名(子节点)compatible

=”gpio-led”;//节点属性pinctrl-names=”default”;pinctrl-0=;led-gpio=;

status=”okay”;};gpio_keys:gpio_keys@0{//节点名(子节点):[@]compatible=”gpio-keys”

;//节点属性pinctrl-names=”default”;pinctrl-0=;#address-cells=;#size-cells=;autorepeat;

key1@1{//节点名(子节点)[@]label=”USER-KEY1″;//节点属性key-value键值对linux,code=;gpios=<&gpio1

18GPIO_ACTIVE_LOW>;gpio-key,wakeup;};};}1. 设备树文件都由根节点开始,每个设备只有一个根节点(如果包含多个文件,根节点则会合并),其它所有设备都作为子节点存在,由节点名和一组节点属性构成。

2. 节点属性都是有key-value的键值对来描述,并以 ; 结束3. 节点间可以嵌套形成父子关系,这样可以方便描述设备间的关系4. 节点名支持[@]的格式,其中后面的unit_address可选,一般为设备地址,这是为了用于保证节点是唯一的标识,当然用其它数字也可以。

同时,节点名也支持:[@]的格式, 这里的label就是节点的标签别名,我们可以&来直接访问节点如对于gpio_keys: gpio_keys@0 可以通过&gpio_keys来访问clock@ gpio_keys@0,后面我们就将用到这个说明。

5. 在设备树中查找节点需要完整的节点路径,对于项目来说,直接修改官方的dts文件是不推荐的,如果自己建立路径,又过于复杂,因此设备树提供通过标注引用的方式,允许我们在其它文件中修改已存在的节点,或者添加新的节点,对于节点的合并原理,包含以下原则:

a. 不同的属性信息进行合并 b. 相同的属性信息进行覆写基于这种原则,我们可以通过如下的代码,在已有节点添加更新新的数据,如使用如下代码在gpio_keys: gpio_keys@0中增加节点。

&gpio_key{key2@2{label=”usr-key2”;//…..}}上面就是节点相关的信息,下面就开始深入节点内部,讲述节点内部如何基于属性来定义设备的说明6. 在驱动中可以同///…/的方式访问到指定设备节点。

如上面的访问key1@1节点即为/gpio_keys@0/key1@1方式即可访问到指定key1@1节点1.2.3 节点属性在上一章我们理解了设备树的节点间关系,并讲述了如何添加节点或修改已经存在节点的方法,进一步我们就要抽丝剥茧,讲述属性的说明。

在我们上一章节中,讲到属性是key-value的键值对,这就分两部分讲解设备树的说明1.2.3.1 常见value类型其中value中常见的几种数据形式如下:1. 空类型ranges;空类型,仅需要键值,用来表示真假类型, 或者值可选的类型。

2. 字符串compatible = “simple-bus”;这里”simple-blus”就是属性中对应的字符串值3. 字符串表compatible = “fsl,sec-v4.0-mon”, “syscon”, “simple-mfd”;。

值也可以为字符串列表,中间用,号隔开,这样既可以支持多个字符串的匹配4. 无符号整型/无符号的整型数值offset = ;5. 可编码数组

支持编码的多无符号整数的数组,如reg可以通过#address-cells指定地址单元的数目,#size-cells指定长度单元的数目reg = ;可以通过&的方式,即可引用其它节点的数据,用于后续的处理

clocks = ;1.2.3.2 常用key属性1. compatible 字符串列表类型compatible属性是值是由特定编程模型的一个或多个字符串组成,用于将驱动和设备连接起来,我们在驱动中也是通过compatible来选择设备树中指定的硬件,是非常重要的属性。

compatible的格式一般为:“[,]”如compatible = “arm,cortex-a7”; compatible = “fsl,imx6ul-pxp-v4l2”, “fsl,imx6sx-pxp-v4l2”, “fsl,imx6sl-pxp-v4l2”; compatible = “gpio-led”;

在该模型中,Manufacturer表示厂商,可选Model表示指定型号,一般和模块对应的驱动名称一致(当然不一致也不影响实际功能)在驱动中使用platform_driver中of_match_table里即可使用.compatible用来匹配该对应设备节点,另外匹配时严格的字符串匹配的,所以驱动内的匹配值和设备树中的value要保持一致。

spidev: icm20608@0 { compatible = “alientek,icm20608”; spi-max-frequency = ; reg = ; }; /* 设备树匹配列表 */ static const struct of_device_id icm20608_of_match[] = { { .compatible = “alientek,icm20608” }, { /* Sentinel */ } }; /* SPI驱动结构体 */ static struct spi_driver icm20608_driver = { .probe = icm20608_probe, .remove = icm20608_remove, .driver = { .owner = THIS_MODULE, .name = SPI_ICM_NAME, .of_match_table = icm20608_of_match, }, };

参考上述结构,即可看到通过of_math_table指定设备树匹配列表,找到指定的节点去访问2. model字符串类型指定设备商信息和模块的具体信息,也有用于模块功能说明,和compatible类似,但仅支持单个字符串模式。

model = “Freescale i.MX6 ULL 14×14 EVK Board”;3. status字符串类型 指示设备的运行状态,目前支持的状态列表如下:

4. #address-cell和#size-cell无符号整型#address-cells和#size-cells可以用在任何拥有子节点的设备中,用于描述子节点中”reg”对应属性内部值的信息,其中

#address-cells 用来描述字节点中”reg”对应属性中描述地址列表中cell数目#size-cells 用来描述字节点中”reg”对应属性中描述长度列表中cell数目#address-cells和#size-cells属性不是从devicetree的祖先继承的。

它们需要明确定义,如果未定义,对于设备树则默认按照地址cell为2个,长度cell为1个去解析reg的值soc { #address-cells = ; #size-cells = ; serial { compatible = “ns16550”; reg = ; clock-frequency = ; interrupts = ; interrupt-parent = ; }; };

如这里reg就要被解析为address-1位,值为0x4600, size-1位,值为0x1005. reg 可编码数组类型由任意长度的地址和长度构成,描述设备在父设备地址空间中的总线范围,通过#address-cells和#size-cells变量去解析,另外如果#size-cells的长度位0,则reg中后面关于长度的部分应该去除,reg的举例如下:。

#address-cells = ; //指定address的范围长度 #size-cells = ; //指定size的范围长度 ethphy0: ethernet-phy@0 { compatible = “ethernet-phy-ieee802.3-c22”; reg = ; //实际reg对应的寄存器地址和范围 };

6. ranges或者类型ranges 非空时是一个地址映射/转换表,ranges 属性每个项目由子地址、父地址和地址空间长度

这三部分组成child-bus-address:子总线地址空间的物理地址 parent-bus-address:父总线地址空间的物理地址 length:子地址空间的长度 如果 ranges 属性值为空值,说明不需要进行地址转换。

7. name和device_type字符串类型分别表示节点名称或者设备树类型属性,这两个属性在新版本中已经被废弃,这里就不再讨论,可以通过《Devicetree Specifification Release v0.2》的2.3章节查看。

除上述的标准属性外,设备树也支持其它属性如clock-frequency //指定模块的时钟频率 label //指定可读的标签,用于开发者查看的属性 current-speed: //串口的波特率

等,此外也支持自定义的属性键值对来实现符合自己驱动应用的需求1.3 设备树在驱动中的应用上面描述的基本都是设备树语法的部分,不过对于驱动来说,如何从设备树中提取有效的设备信息,从而在驱动中脱离对硬件寄存器的直接访问,如何把设备树用于嵌入式驱动开发中,这部分内容也相当重要,对于嵌入式Linux设备,语法树是在/sys/firmware/devicetree下,可使用。

ls /sys/firmware/devicetree/base/来查看当前根节点下的设备树文件,如下:

对于驱动来说,可以使用内核提供访问设备树的函数用于匹配节点的接口来访问设备树1.1.1 内核设备树访问函数内核访问设备树的函数主要包含获取节点的函数和获取节点内部属性的函数,这些函数都定义在内核include/linux/of.h中。

//根据节点路径获取设备节点信息 structdevice_node*of_find_node_by_path(constchar*path)structdevice_node*of_find_node_opts_by_path

(constchar*path,constchar**opts)//根据设备属性获取设备节点信息 structdevice_node*of_find_node_by_name(structdevice_node

*from,constchar*name)structdevice_node*of_find_node_by_type(structdevice_node*from,constchar*type)struct

device_node*of_find_compatible_node(structdevice_node*from,constchar*type,constchar*compat)//根据匹配的of_device_id表格获取node节点(在框架中常用的匹配方式)

staticinlinestructdevice_node*of_find_matching_node_and_match(structdevice_node*from,conststructof_device_id

*matches,conststructof_device_id**match);根据这些信息,我们就可以实现如下代码,找到设备树内的指定节点,代码如下:/*获取设备节点*/nd=of_find_node_by_path

(“/usr_gpios/beep”);if(nd==NULL){return-EINVAL;}else{printk(KERN_INFO”node find by path ok\n”);}nd=of_find_compatible_node

(NULL,NULL,”gpio-beep”);if(nd==NULL){return-EINVAL;}else{printk(KERN_INFO”beep node find by compatible ok

\n”);}在获取设备节点后,我们可以通过内核提供的接口对节点内的key-value键值对进一步读取,具体接口如下://提取通用属性的接口 structproperty*of_find_property

(conststructdevice_node*np,constchar*name,int*lenp);intof_property_read_u32_index(conststructdevice_node

*np,constchar*propname,u32index,u32*out_value);intof_property_read_string(structdevice_node*np,constchar

*propname,constchar**out_string);//用于获取硬件信息的接口 intof_get_named_gpio(structdevice_node*np,constchar*propname

,intindex);intof_get_gpio(structdevice_node*np,intindex);在了解这些代码后,就可以实现如下代码访问设备树内的参数属性,具体如下proper=of_find_property

(nd,”name”,NULL);if(proper!=NULL)printk(KERN_INFO”%s:%s\n”,proper->name,(char*)proper->value);ret=of_property_read_string

(nd,”status”,&pStr);if(pStr!=NULL)printk(KERN_INFO”status:%s\n”,pStr);而在部分框架中,也对上述接口进一步封装,如platform_device_driver中需要提供的of_device_id就是更进一步的调用接口,通过

staticconststructof_device_idkey_of_match[]={{.compatible=”usr-gpios”},{/* Sentinel */}};结构,也能实现对设备树的匹配,这在很多驱动框架中都是十分常用的,需要在实践中总结理解。

1.4 总结至此,对设备树的语法进行了比较全面的讲解,当然这里面还有很多不完善的地方,如对中断控制器和中断相关的语法目前尚未说明,另外很多部分的理解受水平限制有遗漏或者错误的地方,如果有发现,请及时反馈

当然在实际驱动开发中,熟悉这些知识还是不够的,日常打交道还有很多是芯片厂商或者方案商定义的具有特定功能的自定义属性键值对,这就需要长期的积累了不过理解了设备树语法的原理,反过来去理解这些自定义属性,是清晰明了的。

这篇文章只能算是对设备树语法的入门指引,如果希望深入去掌握嵌入式驱动开发,还是配合着实际产品的硬件框架,在实际任务的维护或者修改设备树,再结合参考资料中提到的文档和本文的说明,带着目的去学习,才是高效且快速的方式。

参考资料:2. imx6ull设备树文件

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容