04_Linux设备树DTB文件OF函数

news2024/9/25 1:18:25

目录

创建小型模板设备树

添加cpus节点

添加soc节点

添加ocram节点

添加aips1、aips2和aips3这三个子节点

添加eespil、usbotg1和rngb这三个外设控制器节点

设备树在系统中的体现

根节点“/”各个属性

根节点“/”各子节点

特殊节点

aliases子节点

chosen子节点

Linux内核解析DTB文件

设备树常用OF操作函数

查找节点的OF函数

of_find_node_by_name函数

of find node_by type 函数

of_find_compatible_node函数

提取属性值的OF函数

of_find_property函数

of_property_count_elems_of_size函数

of_property_read_u8_array 函数

of_property_read_u8函数

of_n_addr_cells函数

of_n_size_cells函数

其他常用的OF函数

of_get_address函数

of_translate_address函数

of_address_to_resource函数

of_iomap函数


创建小型模板设备树

根据前面讲解的语法,从头到尾编写一个小型的设备树文件。当然了,这个小型设备树没有实际的意义,做这个的目的是为了掌握设备树的语法。在实际产品开发中,我们是不需要完完全全的重写一个.dts设备树文件,一般都是使用 SOC 厂商提供好的.dts文件,我们只需要在上面根据自己的实际情况做相应的修改即可。在编写设备树之前要先定义一个设备,我们就以I.MX6ULL这个SOC为例,我们需要在设备树里面描述的内容如下:

1.I.MX6ULL这个Cortex-A7 架构的32位CPU。

2.I.MX6ULL内部ocram,起始地址 0x00900000,大小为128KB(0x20000)。

3.I.MX6ULL内部aips1域下的ecspil外设控制器,寄存器起始地址为0x02008000,大小为 0x4000。

4.I.MX6ULL内部 aips2域下的 usbotg1外设控制器,寄存器起始地址为0x02184000,大小为 0x4000。

5.I.MX6ULL内部aips3域下的rngb外设控制器,寄存器起始地址为0x02284000,大小为 0x4000。

为了简单起见,我们就在设备树里面就实现这些内容即可,首先,搭建一个仅含有根节点“/”的基础的框架,新建一个名为myfirst.dts文件,在里面输入如下所示内容:

 设备树框架很简单,就一个根节点"/”,根节点里面只有一个compatible属性。我们就在这个基础框架上面将上面列出的内容一点点添加进来。

添加cpus节点

首先添加CPU节点,I.MX6ULL采用Cortex-A7架构,而且只有一个CPU,因此只有一个cpu0节点,完成以后如下所示:

 第4-14行,cpus节点,此节点用于描述SOC内部的所有CPU,因为I.MX6ULL只有一个CPU,因此只有一个cpu0子节点。

添加soc节点

像 uart, iic控制器等等这些都属于SOC内部外设,因此一般会创建一个叫做soc的父节点来管理这些SOC内部外设的子节点,添加soc节点以后的myfirst.dts文件内容如下所示:

 第17-22行,soc节点,soc节点设置#address-cells=<1>, #size-cells=<1>,这样soc子节点的 re 属性中起始地占用一个字长,地址空间长度也占用一个字长。

第21行, ranges属性,ranges属性为空,说明子空间和父空间地址范围相同。

添加ocram节点

根据第2点的要求,添加ocram节点, ocram是I.MX6ULL内部RAM,因此ocram节点应该是soc节点的子节点。ocram起始地址为0x00900000,大小为128KB(0x20000),添加ocram节点以后 myfirst.dts文件内容如下所示:

 第24-27行, ocram节点,第24行节点名字@后面的0x00900000就是ocram的起始地址。第26行的reg属性也指明了ocram内存的起始地址为0x00900000,大小为0x20000

添加aips1、aips2和aips3这三个子节点

I.MX6ULL内部分为三个域:aips1~3,这三个域分管不同的外设控制器,aips1~3这三个域对应的内存范围如表所示:

 我们先在设备树中添加这三个域对应的子节点。aips1~3这三个域都属于soc节点的子节点,完成以后的myfirst.dts文件内容如下所示:

 第30~36行,aips1节点。

第39-45行,aips2节点。

第48-54行, aips3节点。

添加eespil、usbotg1和rngb这三个外设控制器节点

最后我们在myfirst.dts文件中加入 ecspil,usbotg1和mgb这三个外设控制器对应的节点,其中 ecspil属于 aips1的子节点,usbotg1属于aips2的子节点,rngb属于aips3的子节点。最终的myfirst.dts文件内容如下:

 第38-44行,ecspil外设控制器节点。

第56-60行, usbotg1外设控制器节点。

第72~75行,rngb 外设控制器节点。

至此,myfirst.dts 这个小型的模板设备树就编写好了,基本和imx6ull.dtsi很像,可以看做是 imx6ull.dtsi的缩小版。在myfirst.dts 里面我们仅仅是编写了I.MX6ULL的外设控制器节点,像IIC 接口,SPI 接口下所连接的具体设备我们并没有写,因为具体的设备其设备树属性内容不同。

 

设备树在系统中的体现

Linux内核启动的时候会解析设备树中各个节点的信息,并且在根文件系统的/proc/devicetree目录下根据节点名字创建不同文件夹,如图43.5.1所示:

 图就是目录/proc/device-tree目录下的内容,/proc/device-tree目录下是根节点“/”的所有属性和子节点,依次来看一下这些属性和子节点。

根节点“/”各个属性

在图中,根节点属性属性表现为一个个的文件(图中细字体文件),比如图中的“#address-cells"、"#size-cells"、"compatible”、"model”和"name”这5个文件,它们在设备树中就是根节点的5个属性。既然是文件那么肯定可以查看其内容,输入 cat命令来查看 model和compatible这两个文件的内容,结果如图所示:

 从图可以看出,文件model的内容是"Freescale I.MX6 ULL 14x14 EVK Board",文件

compatible的内容为"fsl,imx6ull-14x14-evkfsl,imx6ull”。

打开文件imx6ull-alientek-emmc.dts查看一下,这不正是根节点“/”的model和compatible 属性值吗!

根节点“/”各子节点

图中各个文件夹(图中粗字体文件夹)就是根节点“/”的各个子节点,比如“aliases”、“backlight"、“chosen”和“clocks”等等。大家可以查看一下 imx6ull-alientek-emmc.dts 和imx6ull.dtsi 这两个文件,看看根节点的子节点都有哪些,看看是否和图中的一致。/proc/device-tree 目录就是设备树在根文件系统中的体现,同样是按照树形结构组织的,进入/proc/device-tree/soc目录中就可以看到soc节点的所有子节点,如图所示:

 和根节点“/”一样,图中的所有文件分别为soc节点的属性文件和子节点文件夹。大家可以自行查看一下这些属性文件的内容是否和imx6ull.dtsi中soc节点的属性值相同,也可以进入"busfreq”这样的文件夹里面查看soc节点的子节点信息。

特殊节点

在根节点“/”中有两个特殊的子节点:aliases和chosen,我们接下来看一下这两个特殊的子节点。

aliases子节点

打开imx6ull.dtsi文件, aliases节点内容如下所示:

 单词aliases的意思是“别名”,因此aliases节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。不过我们一般会在节点命名的时候会加上label,然后通过&label来访问节点,这样也很方便,而且设备树里面大量的使用&label的形式来访问节点。

 

chosen子节点

chosen并不是一个真实的设备, chosen节点主要是为了uboot向Linux内核传递数据,重点是bootargs参数。一般.dts文件中chosen节点通常为空或者内容很少,imx6ull-alientekemmc.dts中chosen节点内容如下所示:

 从示例代码43.6.2.1中可以看出, chosen节点仅仅设置了属性"stdout-path”,表示标准输·出使用uart1。但是当我们进入到/proc/device-tree/chosen目录里面,会发现多了bootargs这个属性,如图所示:

 输入cat命令查看bootargs这个文件的内容,结果如图所示:

 从图可以看出, bootargs这个文件的内容为"console=ttymxc0,115200....",这个不就是在 uboot中设置的bootargs环境变量的值吗?现在有两个疑点:

1.我们并没有在设备树中设置chosen节点的bootargs属性,那么图中bootargs这个属性是怎么产生的?

2.为何bootargs文件的内容和uboot中bootargs环境变量的值一样?它们之间有什么关系?

前面uboot的时候说uboot 在启动Linux内核的时候会将bootargs的值传递给Linux内核, bootargs会作为Linux内核的命令行参数, Linux内核启动的时候会打印出命令行参数(也就是uboot传递进来的bootargs的值),如图所示:

 既然chosen节点的bootargs属性不是我们在设备树里面设置的,那么只有一种可能,那就是uboot自己在chose节点里面添加了bootargs属性!并且设置bootargs属性的值为 bootargs环境变量的值。因为在启动Linux内核之前,只有uboot知道bootargs环境变量的值,并且uboot也知道.dtb设备树文件在DRAM中的位置,因此uboot的“作案”嫌疑最大。在uboot源码中全局搜索“chosen”这个字符串,看看能不能找到一些蛛丝马迹。果然不出所料,在common/fdt_support.c文件中发现了"chosen"的身影, fdt_support.c文件中有个fdt_chosen函数,此函数内容如下所示:

 第288行,调用函数fdt_find_or_add_subnode从设备树(.dtb)中找到chosen节点,如果没有找到的话就会自己创建一个chosen节点。

第292行,读取 uboot 中 bootargs 环境变量的内容。

第294行,调用函数fdt_setprop向chosen节点添加bootargs属性,并且bootargs属性的值就是环境变量 bootargs的内容。

证据“实锤”了,就是uboot中的fdt_chosen函数在设备树的chosen节点中加入了bootargs属性,并且还设置了bootargs属性值。接下来我们顺着fdt_chosen函数一点点的抽丝剥茧,看看都有哪些函数调用了fdt_chosen,一直找到最终的源头。这里我就不卖关子了,直接告诉大家整个流程是怎么样的,见图:

 图中框起来的部分就是函数do_bootm_linux函数的执行流程,也就是说do_bootm_linux函数会通过一系列复杂的调用,最终通过fdt_chosen函数在chosen节点中加入了bootargs属性。而我们通过bootz命令启动Linux内核的时候会运行do_bootm_linux函数,至此,真相大白,一切事情的源头都源于如下命令:

 当我们输入上述命令并执行以后, do_bootz函数就会执行,然后一切就按照图中所示的流程开始运行。

Linux内核解析DTB文件

Linux内核在启动的时候会解析DTB文件,然后在/proc/device-tree目录下生成相应的设备树节点文件。接下来我们简单分析一下Linux内核是如何解析DTB文件的,流程如图所示:

  从图中可以看出,在start_kernel函数中完成了设备树节点解析的工作,最终实际工作的函数为unflatten_dt_node。

绑定信息文档

设备树是用来描述板子上的设备信息的,不同的设备其信息不同,反映到设备树中就是属性不同。那么我们在设备树中添加一个硬件对应的节点的时候从哪里查阅相关的说明呢?在Linux内核源码中有详细的.txt文档描述了如何添加节点,这些txt文档叫做绑定文档,路径为:Linux源码目录/Documentation/devicetree/bindings,如图所示:

 比如我们现在要想在I.MX6ULL这颗SOC的I2C下添加一个节点,那么就可以查看· Documentation/devicetree/bindings/i2c/i2c-imx.txt,此文档详细的描述了I.MX系列的 SoC如何在设备树中添加I2C设备节点,文档内容如下所示:

 有时候使用的一些芯片在Documentation/devicetree/bindings目录下找不到对应的文档,这个时候就要咨询芯片的提供商,让他们给你提供参考的设备树文件。

设备树常用OF操作函数

设备树描述了设备的详细信息,这些信息包括数字类型的、字符串类型的、数组类型的,,我们在编写驱动的时候需要获取到这些信息。比如设备树使用reg属性描述了某个外设的寄存器地址为0X02005482,长度为0X400,我们在编写驱动的时候需要获取到reg属性的

查找节点的OF函数

设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的其他属性信息,必须先获取到这个设备的节点。Linux内核使用device_node结构体来描述一个节点,此结构体定义在文件 include/linux/of.h 中,定义如下:

 

of_find_node_by_name函数

of_find_node_by_name函数通过节点名字查找指定的节点,函数原型如下:

 函数参数和返回值含义如下:

from:开始查找的节点,如果为NULL表示从根节点开始查找整个设备树。

name:要查找的节点名字。

返回值:找到的节点,如果为NULL表示查找失败。

of find node_by type 函数

of_find_node_by_type函数通过device type属性查找指定的节点,函数原型如下:

函数参数和返回值含义如下:

from:开始查找的节点,如果为NULL表示从根节点开始查找整个设备树。

type:要查找的节点对应的type字符串,也就是device_type属性值。

返回值:找到的节点,如果为NULL表示查找失败。

of_find_compatible_node函数

of_find_compatible_node函数根据device_type和compatible这两个属性查找指定的节点,函数原型如下:

 函数参数和返回值含义如下:

from:开始查找的节点,如果为NULL表示从根节点开始查找整个设备树。

matches: of_device_id匹配表,也就是在此匹配表里面查找节点。

Match:找到的匹配的of_device_id。

返回值:找到的节点,如果为NULL表示查找失败

提取属性值的OF函数

节点的属性信息里面保存了驱动所需要的内容,因此对于属性值的提取非常重要, Linux内核中使用结构体property表示属性,此结构体同样定义在文件include/linux/of.h中,内容如下:

 

of_find_property函数

of_find_property函数用于查找指定的属性,函数原型如下:

 函数参数和返回值含义如下:

Np:设备节点。

name:属性名字。

Lenp:属性值的字节数

返回值:找到的属性。

of_property_count_elems_of_size函数

of_property_count_elems_of_size函数用于获取属性中元素的数量,比如reg属性值是一个数组,那么使用此函数可以获取到这个数组的大小,此函数原型如下:

 

函数参数和返回值含义如下:

np:设备节点。

proname::需要统计元素数量的属性名字。

elem_size:元素长度。

返回值:得到的属性元素数量。

of_property_read_u8_array 函数

of_property_read_u16_array 函数

of_property_read_u32_array 函数

of_property_read_u64_array 函数

这 4 个函数分别是读取属性中 u8、ul6、u32和u64类型的数组数据,比如大多数的reg属性都是数组数据,可以使用这4个函数一次读取出reg属性中的所有数据。

这四个函数的原型如下:

 函数参数和返回值含义如下:

np:设备节点。

proname:要读取的属性名字。

out_value:读取到的数组值,分别为 u8、ul6、u32 和 u64。

Sz:要读取的数组元素数量。

返回值:0,读取成功,负值,读取失败,-EINVAL表示属性不存在,-ENODATA表示没有要读取的数据,-EOVERFLOW表示属性值列表太小。

of_property_read_u8函数

of_property_read_u16函数

of_property_read_u32函数

of_property_read_u64函数

有些属性只有一个整形值,这四个函数就是用于读取这种只有一个整形值的属性,分别用于读取 u8、u16、u32和u64类型属性值,函数原型如下:

 函数参数和返回值含义如下:

np:设备节点。

proname:要读取的属性名字。

out_value:读取到的数组值。

返回值:0,读取成功,负值,读取失败,-EINVAL表示属性不存在,-ENODATA表示没有要读取的数据,-EOVERFLOW表示属性值列表太小。

of_n_addr_cells函数

of_n_addr_cells函数用于获取#address-cells属性值,函数原型如下:

 函数参数和返回值含义如下:

np:设备节点。

返回值:获取到的#address-cells属性值。

of_n_size_cells函数

of_size_cells函数用于获取#size-cells属性值,函数原型如下:

 函数参数和返回值含义如下:

np:设备节点。

返回值:获取到的#size-cells属性值。

其他常用的OF函数

of_device_is_compatible函数

of_device_is_compatible函数用于查看节点的compatible属性是否有包含compat指定的字符串,也就是检查设备节点的兼容性,函数原型如下:

 函数参数和返回值含义如下:

device:设备节点。

compat:要查看的字符串。

返回值:0,节点的compatible属性中不包含compat指定的字符串;正数,节点的compatible属性中包含compat指定的字符串。

of_get_address函数

of_get_address函数用于获取地址相关属性,主要是"reg"或者"assigned-addresses"属性值,函数原型如下:

 函数参数和返回值含义如下:

dev:设备节点。

Index:要读取的地址标号。

Size:地址长度。

flags:参数,比如IORESOURCE_IO、IORESOURCE_MEM等

返回值:读取到的地址数据首地址,为NULL的话表示读取失败。

of_translate_address函数

of_translate_address函数负责将从设备树读取到的地址转换为物理地址,函数原型如下:

 函数参数和返回值含义如下:

Dev:设备节点。

in_addr:要转换的地址。

返回值:得到的物理地址,如果为OF_BAD_ADDR的话表示转换失败。

of_address_to_resource函数

IIC、SPI、GPIO等这些外设都有对应的寄存器,这些寄存器其实就是一组内存空间, Linux内核使用resource结构体来描述一段内存空间,“resource”翻译出来就是“资源”,因此用 resource结构体描述的都是设备资源信息,resource结构体定义在文件 include/linux/ioport.h中,定义如下:

 对于32位的SOC来说,resource_size_t是u32类型的。其中start表示开始地址,end表示,结束地址, name是这个资源的名字, flags是资源标志位,一般表示资源类型,可选的资源标志定义在文件include/linux/ioport.h中,如下所示:

 大家一般最常见的资源标志就是IORESOURCE_MEM、IORESOURCE_REG和IORESOURCE_IRQ等。接下来我们回到of_address_to_resource函数,此函数看名字像是从设备树里面提取资源值,但是本质上就是将reg属性值,然后将其转换为resource结构体类型,函数原型如下所示:

函数参数和返回值含义如下:

dev:设备节点。

Index:地址资源标号。

r:得到的resource类型的资源值。

返回值:0,成功;负值,失败。

of_iomap函数

of_iomap函数用于直接内存映射,以前我们会通过ioremap函数来完成物理地址到虚拟地址的映射,采用设备树以后就可以直接通过of_iomap函数来获取内存地址所对应的虚拟地址,不需要使用ioremap函数了。当然了,你也可以使用ioremap函数来完成物理地址到虚拟地址的内存映射,只是在采用设备树以后,大部分的驱动都使用of_iomap函数了。of_iomap函数本质上也是将reg属性中地址信息转换为虚拟地址,如reg属性有多段的话,可以通过index参数指定要完成内存映射的是哪一段, of_iomap函数原型如下:

 函数参数和返回值含义如下:

np:设备节点。

index: reg属性中要完成内存映射的段,如果reg属性只有一段的话index就设置为0

返回值:经过内存映射后的虚拟内存首地址,如果为NULL的话表示内存映射失败。

关于设备树常用的OF函数就先讲解到这里,Linux内核中关于设备树的OF函数不仅仅只有前面讲的这几个,还有很多OF函数我们并没有讲解,这些没有讲解的OF函数要结合具体的驱动,比如获取中断号的OF函数、获取GPIO的OF函数等等,这些OF函数后面的驱动实验中再详细的讲解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

转专业之我见

写在前面 如果你点进来看这篇文章&#xff0c;说明你的至少有想转专业的想法甚至心里是趋向于转专业的。 但是或许是因为学校只有一次转专业的机会或者有别的原因让你犹豫不决&#xff0c;那么你首先要明确你为什么想要转专业&#xff0c;是因为本专业是天坑专业&#xff0c;…

UI 自动化测试 —— selenium的简单介绍和使用

selenium 是 web 应用中基于 UI 的自动化测试框架&#xff0c;支持多平台、多浏览器、多语言。 提到 UI 自动化就先了解什么是自动化测试&#xff1f; 目录 1. 自动化测试 2. UI 自动化 2.1 UI 自动化的特点 2.2 UI 自动化测试的优缺点 2.3 UI 自动化测试的使用对象 2.4…

PPG信号和ECG信号检测血管年龄

PAT 通常用作动脉硬度的间接测量值或心血管健康的指标。它与各种生理和病理状况有关&#xff0c;例如高血压、动脉硬化和内皮功能障碍。 通过脉搏到达时间进行测量&#xff0c;简单来说就是 先从脉冲传输时间 PPG 数据集中提取数据&#xff0c;提取此数据集中每个对象的脉冲到…

【Python从入门到进阶】24、urllib获取网站电影排行

接上篇《23、urllib使用post请求百度翻译》 上一篇我们讲解了如何使用urllib实现百度翻译的效果。本篇我们来讲解如何使用urllib抓取某某电影排行榜信息。 一、某某电影介绍 1、某某电影网站 某某电影成立于2005年&#xff0c;最初只是一个小型的电影社区&#xff0c;但随着…

【备战秋招】每日一题:2023.05-B卷-华为OD机试 - 报文重排序

为了更好的阅读体检&#xff0c;可以查看我的算法学习博客报文重排序 题目描述 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓中区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 输入描述 输入第…

改进YOLOv8 | 优化器篇 | YOLOv8 引入谷歌 Lion 优化器

论文地址:https://arxiv.org/pdf/2302.06675.pdf 代码地址:https://github.com/google/automl/tree/master/lion 我们提出了一种将算法发现作为程序搜索的方法,并将其应用于发现用于深度神经网络训练的优化算法。我们利用高效的搜索技术来探索一个无限且稀疏的程序空间。为了…

【SCADA】测试用KingIOServer采集杰控OPC DA服务器数据

Hello&#xff0c;大家好&#xff0c;我是雷工&#xff01; 现场做数据采集时经常会遇到需要通过OPC采集数据的情况&#xff0c;本篇测试KingIOServer采集北京杰控组态软件的OPCDA服务器数据。 以下为测试记录过程。 一、KingIOServer的OPC DA数据采集介绍 KingIOServer可以作…

Vue中如何进行分布式日志管理与日志分析

Vue中如何进行分布式日志管理与日志分析 在现代应用程序中&#xff0c;日志是一项重要的功能&#xff0c;用于帮助开发人员和运维人员了解应用程序的行为并进行故障排除。随着应用程序的规模和复杂性的增加&#xff0c;日志管理和分析变得越来越困难。本文将介绍如何在Vue应用…

JSON对象花样进阶

JSON 对象使用在大括号{ }中书写。 对象可以包含多个 key/value&#xff08;键/值&#xff09;对。 key 必须是字符串&#xff0c;value 可以是合法的 JSON 数据类型&#xff08;字符串, 数字, 对象, 数组, 布尔值或 null&#xff09;。 key 和 value 中使用冒号(:)分割。 每个…

Postman接口自动化之postman脚本编写

这是之前搞的接口自动化方案&#xff0c;已经在业务测试中实现了使用postman编写接口脚本&#xff0c;通过GitHubJenkinsemail html report实现了接口自动化&#xff0c;现在分块整理一下。 postman脚本编写 1、创建集合 和 目录&#xff1a; 一条业务线下的接口可以放到一个…

ACL2023 | 大模型如何快速构建指令遵循数据集?self-instruct:用175条种子数据追上InstructGPT001效果

一、概述 title&#xff1a;SELF-INSTRUCT: Aligning Language Models with Self-Generated Instructions 论文地址&#xff1a;https://arxiv.org/abs/2212.10560 代码&#xff1a;GitHub - yizhongw/self-instruct: Aligning pretrained language models with instruction…

chatgpt赋能python:Python怎么输出Unicode值

Python怎么输出Unicode值 Python 是一种高级编程语言&#xff0c;因其简单易学和快速开发已成为许多开发者的首选。Python 可以输出多种数据类型&#xff0c;包括字符串和数字。 在许多情况下&#xff0c;输出 Unicode 值是必需的&#xff0c;本文将介绍在 Python 中如何输出 …

shardingsphere第二课-shardingsphere-jdbc的基本使用及各种分片策略

第一章介绍 一、ShardingJDBC客户端分库分表 ShardingSphere-JDBC 定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库&#xff0c;以 jar 包形式提供服务&#xff0c;无需额外部署和依赖&#xff0c;可理解为增强版的 JDBC 驱动…

chatgpt赋能python:Python中如何输入一个列表

Python中如何输入一个列表 输入一个列表是Python编程的基本任务之一。列表可以看做是一种序列&#xff0c;其中包含多个元素&#xff0c;用逗号隔开&#xff0c;并用方括号括起来。在Python中&#xff0c;列表是一种非常常见的数据类型&#xff0c;常用于存储和处理一系列相关…

断言操作符介绍

目录 1.延时操作符&#xff08;##&#xff09; 1.1 ##m 1.2 ##[m:n] 2.蕴含操作符&#xff08;|>,|->&#xff09; 2.1 |>操作符 2.2 |->操作符 3 重复操作符 ([*m][->m][m]) 3.1 连续重复操作符&#xff08;[*m][*m:n]&#xff09; 3.2 跟随重复操作…

Java选择题刷题记录5

Java堆栈 图片来自https://www.cnblogs.com/cici-new/p/14963762.html 数组、String都在堆里 枚举类 1.枚举类可以实现一个或多个接口&#xff0c;使用enum定义的枚举类默认继承java.lang.Enum类&#xff0c;而不是默认继承Object类&#xff0c;其中 java.lang.Enum类实现了…

机器视觉硬件的选择-标定板

康耐视智能相机Insight-缺陷检测 一>棋盘格的作用 a>畸变校正 径向畸变,径向畸变就是沿着透镜半径方向分布的畸变,产生原因是光线在原理透镜中心的地方比靠近中心的地方更加弯曲,这种畸变在短焦镜头中表现更加明显,径 向畸变主要包括桶形畸变和枕形畸变两种。以下分别…

chatgpt赋能python:Python输入π的方法及其应用

Python输入π的方法及其应用 Python是一门强大的编程语言&#xff0c;其支持的数学函数功能能够帮助用户完成各种复杂的计算操作。当我们需要在Python代码中使用π值时&#xff0c;不同的场景需要不同的处理方法。本文将详细介绍如何在Python中输入π值&#xff0c;并且探讨它…

Ansible 的脚本 --- playbook 剧本

playbook的相关知识 playbook 的简介 playbook是 一个不同于使用Ansible命令行执行方式的模式&#xff0c;其功能更强大灵活。 简单来说&#xff0c;playbook是一个非常简单的配置管理和多主机部署系统&#xff0c; 不同于任何已经存在的模式&#xff0c;可作为一个适合部署…

【C++】STL之string类(2)

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…