驱动开发之设备树语法

目录

0.设备树由来

1.设备树概念

1.1.DTS、DTB 和 DTC 和 dtsi 概念

2.设备树语法

2.1.例子

 2.2.设备节点

2.2.1.节点命名

2.2.2节点数据类型

2.2.3.根节点

2.2.4.属性介绍

2.2.4.1.compatible属性

2.2.4.2.name属性

2.2.4.3.status 属性

2.2.4.5.unit-address属性

2.2.4.6.address-cells属性与size-cells属性

2.2.4.7reg属性

2.2.4.8.range属性

2.2.4.9device_type 属性

2.2.4.10.aliases 属性

2.2.4..11chosen属性

2.2.5.向节点追加或修改内容

2.3.设备树体现 存储

2.4.Linux 内核解析 DTB 文件

3.设备树相关的接口函数

3.1.查找节点的 OF 函数

3.1.1.of_find_node_by_name 函数

3.1.2.of_find_node_by_type 函数

3.1.3.of_find_compatible_node 函数

3.1.4.of_find_matching_node_and_match 函数

3.1.5.of_find_node_by_path 函数

3.1.6查找父节点的 OF 函数

3.1.7.查找子节点的 OF 函数

3.2.提取属性值的 OF 函数

3.2.1.of_find_property 函数

3.2.2.of_property_count_elems_of_size 函数

3.2.3.of_property_read_u32_index 函数


0.设备树由来

通过前面platform实验,使用platform总线,device与driver需要匹配才可以,device主要是存储一些硬件信息的,传递给driver使用。这样就会导致大量的硬件信息在linux内核源码里面,arch/arm/mach-xxx 和 arch/arm/plat-xxx 文件夹下,这些文件夹里面的文件就是对应平台下 的板级信息,当 Linux 之父 linus 看到 ARM 社区向 Linux 内核添加了大量“无用”、冗余 的板级信息文件,不禁的发出了一句“This whole ARM thing is a f*cking pain in the ass”。从此以 后 ARM 社区就引入了 PowerPC 等架构已经采用的设备树(Flattened Device Tree),将这些描述 板级硬件信息的内容都从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文 件就叫做设备树,文件扩展名为.dts。

1.设备树概念

设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(Device Tree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如 CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等。

说白了设备树就是存储硬件信息的描述文件,由系统·解析设备树文件,生成相应的device,然后与相应的驱动进行匹配,driver也可以通过设备树设备信息获取设备硬件信息,这些信息都是在设备树里面的。

1.1.DTS、DTB 和 DTC 和 dtsi 概念

DTS 是设备树源码文件,设备树源文件扩展名为.dts

DTB 是将 DTS 编译以后得到的二进制文件

DTC是将么将.dts 编译为.dtb的工具,DTC 工具源码在 Linux 内核的 scripts/dtc 目录下

dtsi,由于一个SoC可能对应多个设备(一个SoC可以对应多个产品和电路板),这些.dts文件势必须包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个设备共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的设备对应的.dts就包括这个.dtsi。

2.设备树语法

2.1.例子

/ {aliases {can0 = &flexcan1;};cpus {#address-cells = <1>;#size-cells = <0>;cpu0: cpu@0 {compatible = "arm,cortex-a7";device_type = "cpu";reg = <0>;};};intc: interrupt-controller@00a01000 {compatible = "arm,cortex-a7-gic";#interrupt-cells = <3>;interrupt-controller;reg = <0x00a01000 0x1000>,<0x00a02000 0x100>;};
}

 2.2.设备节点

设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设 备节点,每个节点都通过一些属性信息来描述节点信息,属性就是键—值对。每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任 意的字节流。

2.2.1.节点命名

label: node-name@unit-address

“label" 前面的是节点标签(label)

“node-name” 是节点名字,为 ASCII 字符串,节点名字应该能够清晰的描述出节点的 功能

“unit-address”一般表示设备的地址或寄 存器首地址,如果某个节点没有地址或者寄存器的话“unit-address”可以不要。

如:

cpu0:cpu@0

cpu0是标签,cpu这个设备,寄存器地址是0,

2.2.2节点数据类型

①、字符串 compatible = "arm,cortex-a7"; 上述代码设置 compatible 属性的值为字符串“arm,cortex-a7”。

②、32 位无符号整数 reg =<0> ; 上述代码设置 reg 属性的值为 0,reg 的值也可以设置为一组值,比如:  reg = <0x00a01000 0x1000>, <0x00a02000 0x100>;,reg是描述地址字段

③、字符串列表 属性值也可以为字符串列表,字符串和字符串之间采用“,”隔开,如下所示: compatible = "fsl,imx6ull-gpmi-nand", "fsl, imx6ul-gpmi-nand"; 上述代码设置属性 compatible 的值为“fsl,imx6ull-gpmi-nand”和“fsl, imx6ul-gpmi-nand”。

2.2.3.根节点

“/”是根节点,每个设备树文件只有一个根节点。如果dtsi与dts这两个文件都有一个“/”根节点,这种情况是允许的,因为 这两个“/”根节点的内容会合并成一个根节点

2.2.4.属性介绍

节点是由一堆的属性组成,节点都是具体的设备,不同的设备需要的属性不同,用户可以 自定义属性。除了用户自定义属性,有很多属性是标准属性,Linux 下的很多外设驱动都会使用 这些标准属性。

2.2.4.1.compatible属性

compatible 属性也叫做“兼容性”属性,这是非常重要的一个属性!compatible 属性的值是 一个字符串列表,compatible 属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要 使用的驱动程序,compatible 属性的值格式如下所示:

compatible = "manufacturer,model"

其中 manufacturer 表示厂商,model 一般是模块对应的驱动名字。 一般驱动程序文件都会有一个 OF 匹配表,此 OF 匹配表保存着一些 compatible 值,如果设 备节点的 compatible 属性值和 OF 匹配表中的任何一个值相等,那么就表示设备可以使用这个 驱动。也可以不按照这个格式填,只要与驱动的名字一样,完成匹配就可以了,但是这样阅读性不好,建议还是按照这个模式填写。 

如:

compatible = "fsl,mpc8349-uart", "ns16550"

设备的 compatible 属性应为:. fsl,mpc8349-uart指定确切的设备,并ns16550声明它与 National Semiconductor 16550 UART 的寄存器级兼容。

2.2.4.2.name属性

name 属性值为字符串,name 属性用于记录节点名字,name 属性已经被弃用,不推荐使用 name 属性,一些老的设备树文件可能会使用此属性。

2.2.4.3.status 属性

status 属性是和设备状态有关的,status 属性值也是字符串,字符串是设备的 状态信息

如:

status = "okay";

2.2.4.5.unit-address属性

cpu@0:遵循<name>[@<unit-address>]格式

unit-address就是单元地址,设备的私有地址,在节点reg属性中描述

2.2.4.6.address-cells属性与size-cells属性

这两个属性的值都是无符号 32 位整形,#address-cells 和#size-cells 这两个属性可以用在任 何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells 属性值决定了子节点 reg 属 性中地址信息所占用的字长(32 位),#size-cells 属性值决定了子节点 reg 属性中长度信息所占的字长(32 位)。#address-cells 和#size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性 都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度,reg 属性的格式一为:

reg = <address1 length1 address2 length2 address3 length3……>

每个“address length”组合表示一个地址范围,其中 address 是起始地址,length 是地址长 度,#address-cells 表明 address 这个数据所占用的字长,#size-cells 表明 length 这个数据所占用 的字长

如:

#address-cells =<1> ,#size-cells =<0>

说明 spi4 的子节点 reg 属 性中起始地址所占用的字长为 1,地址长度所占用的字长为 0

2.2.4.7reg属性

reg 属性的值一般是(address,length)对。reg 属性一般用于描 述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。

如:

reg = <<0x02280000 0x4000>;

起始地址为 0x02280000,地址长度为 0x40000 

2.2.4.8.range属性

ranges属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字 矩阵。

ranges 是一个地址映射/转换表,ranges 属性每个项目由子地址、父地址和地址空间长度 这三部分组成:

child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells 确定此物理地址 所占用的字长。

parent-bus-address:父总线地址空间的物理地址,同样由父节点的#address-cells 确定此物 理地址所占用的字长。

length:子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。

如果 ranges 属性值为空值,说明子地址空间和父地址空间完全相同,不需要进行地址转换

如:

ranges = <<0x0 0xe0000000 0x00100000>;

此属性值指定 了一个 1024KB(0x00100000)的地址范围,子地址空间的物理起始地址为 0x0,父地址空间的物 理起始地址为 0xe0000000 

2.2.4.9device_type 属性

device_type 属性值为字符串,IEEE 1275 会用到此属性,用于描述设备的 FCode,但是设 备树没有 FCode,所以此属性也被抛弃了。此属性只能用于 cpu 节点或者 memory 节点 。

2.2.4.10.aliases 属性
    aliases {can0 = &flexcan1;};

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

2.2.4..11chosen属性

chosen 并不是一个真实的设备, chosen 节点主要是为了 uboot 向 Linux 内核传递数据,重点是 bootargs 参数。

chosen 节点的 bootargs 属性不是我们在设备树里面设置的,那么只有一种可能,那就是 uboot 自己在 chosen 节点里面添加了 bootargs 属性!并且设置 bootargs 属性的值为 bootargs环境变量的值。因为在启动 Linux 内核之前,只有 uboot 知道 bootargs 环境变量的值,并且 uboot也知道.dtb 设备树文件在 DRAM 中的位置,感兴趣的,可以看一下uboot源码,common/fdt_support.c 文件中有个 fdt_chosen 函数。

2.2.5.向节点追加或修改内容

引入另外一个内容,那就是如何向节点追加数据,特别是针对在dtsi里面的节点,这种时候就需要追加了,不要直接在节点下修改,除非是给其他soc都使用的

&i2c1 {/* 要追加或修改的内容 */
};

2.3.设备树体现 存储

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

这些设备树信息 都将以一个一个文件进行存储起来,路径结构就按照设备树源文件(dts)里面描述的层级结构来创建文件夹或者文件进行数据存储(有没有感觉和之前给模块传递参数很像,参数都是使用某一个文件进行存储)

2.4.Linux 内核解析 DTB 文件

Linux 内核在启动的时候会解析 DTB 文件,然后在/proc/device-tree 目录下生成相应的设备 树节点文件。Linux 内核是如何解析 DTB 文件的。如下图所示

3.设备树相关的接口函数

设备树描述了设备的详细信息,这些信息包括数字类型的、字符串类型的、数组类型的, 我们在编写驱动的时候需要获取到这些信息 。Linux 内核给我们提供了一系列的函数来获 取设备树中的节点或者属性信息,这一系列的函数都有一个统一的前缀“of_”,所以在很多资 料里面也被叫做 OF 函数。这些 OF 函数原型都定义在 include/linux/of.h 文件中

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

struct device_node {const char *name; /* 节点名字 */const char *type; /* 设备类型 */phandle phandle;const char *full_name; /* 节点全名 */struct fwnode_handle fwnode;struct property *properties; /* 属性 */struct property *deadprops; /* removed 属性 */struct device_node *parent; /* 父节点 */struct device_node *child; /* 子节点 */struct device_node *sibling;struct kobject kobj;unsigned long _flags;void *data;#if defined(CONFIG_SPARC)const char *path_component_name;unsigned int unique_id;struct of_irq_controller *irq_trans;#endif
};

3.1.查找节点的 OF 函数

3.1.1.of_find_node_by_name 函数

作用:of_find_node_by_name 函数通过节点名字查找指定的节点

函数原型如下: struct device_node *of_find_node_by_name(struct device_node *from, const char *name);

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

name:要查找的节点名字。

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

3.1.2.of_find_node_by_type 函数

of_find_node_by_type 函数通过 device_type 属性查找指定的节点,

函数原型如下: struct device_node *of_find_node_by_type(struct device_node *from, const char *type)

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

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

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

3.1.3.of_find_compatible_node 函数

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

函数原型如下: struct device_node *of_find_compatible_node(struct device_node *from, const char *type, const char *compatible)

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

ype:要查找的节点对应的 type 字符串,也就是 device_type 属性值,可以为 NULL,表示 忽略掉 device_type 属性。

compatible:要查找的节点所对应的 compatible 属性列表。

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

3.1.4.of_find_matching_node_and_match 函数

of_find_matching_node_and_match 函数通过 of_device_id 匹配表来查找指定的节点,

函数原 型如下: struct device_node *of_find_matching_node_and_match(struct device_node *from, const struct of_device_id *matches, const struct of_device_id **match)

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

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

match:找到的匹配的 of_device_id。

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

3.1.5.of_find_node_by_path 函数

of_find_node_by_path 函数通过路径来查找指定的节点,

inline struct device_node *of_find_node_by_path(const char *path) 

path:带有全路径的节点名,可以使用节点的别名,比如“/backlight”就是 backlight 这个 节点的全路径。

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

3.1.6查找父节点的 OF 函数

of_get_parent 函数 of_get_parent 函数用于获取指定节点的父节点(如果有父节点的话),

struct device_node *of_get_parent(const struct device_node *node) 

node:要查找的父节点的节点

 返回值:找到的父节点。

3.1.7.查找子节点的 OF 函数

of_get_next_child 函数用迭代的方式查找子节点,

struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev) node:父节点

 prev:前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为 NULL,表示从第一个子节点开始。

返回值:找到的下一个子节点。

3.2.提取属性值的 OF 函数

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

struct property {
char *name; /* 属性名字 */
int length; /* 属性长度 */
void *value; /* 属性值 */
struct property *next; /* 下一个属性 */
unsigned long _flags;
unsigned int unique_id;
struct bin_attribute attr;
};

3.2.1.of_find_property 函数

of_find_property 函数用于查找指定的属性,

property *of_find_property(const struct device_node *np, const char *name, int *lenp) 

np:设备节点

name: 属性名字

 lenp:属性值的字节数

返回值:找到的属性 

3.2.2.of_property_count_elems_of_size 函数

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

int of_property_count_elems_of_size(const struct device_node *np, const char *propname,int elem_size)

 np:设备节点。

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

elem_size:元素长度。

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

3.2.3.of_property_read_u32_index 函数

of_property_read_u32_index 函数用于从属性中获取指定标号的 u32 类型数据值(无符号 32 位),比如某个属性有多个 u32 类型的值,那么就可以使用此函数来获取指定标号的数据值,

int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *out_value)

np:设备节点。

proname: 要读取的属性名字。

index:要读取的值标号。

out_value:读取到的值

int of_property_read_u8_array(const struct device_node *np,
const char *propname, 
u8 *out_values, 
size_t sz)
int of_property_read_u16_array(const struct device_node *np,const char *propname, u16 *out_values, size_t sz)
int of_property_read_u32_array(const struct device_node *np,const char *propname, u32 *out_values,size_t sz)
int of_property_read_u64_array(const struct device_node *np,const char *propname, u64 *out_values,
size_t sz)

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

由于篇幅限制,剩余设备树接口函数将在另一篇继续补充完整。

链接:

设备树接口函数-CSDN博客

参考:

Linux设备树特殊节点( aliases、chosen )介绍_stdout-path-CSDN博客

【Linux驱动开发】设备树详解(二)设备树语法详解_linux设备树语法-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024050302-重学 Java 设计模式《实战享元模式》

重学 Java 设计模式&#xff1a;实战享元模式「基于Redis秒杀&#xff0c;提供活动与库存信息查询场景」 一、前言 程序员&#x1f468;‍&#x1f4bb;‍的上下文是什么&#xff1f; 很多时候一大部分编程开发的人员都只是关注于功能的实现&#xff0c;只要自己把这部分需求…

apifox 生成签名

目录 前言准备编写签名脚本签名说明捋清思路编码获取签名所需的参数生成签名将签名放到合适的位置完整代码 在apifox中配置脚本新增公共脚本引用公共脚本添加环境变量 参考 前言 略 准备 查看apifox提供的最佳实践文章&#xff1a;接口签名如何处理 编写签名脚本 签名说明…

【遗传算法】【机器学习】【Python】常见交叉方法(二)、多点交叉和均匀交叉

往期遗传算法文章见&#xff1a; 【遗传算法】【机器学习】【Python】常见交叉方法&#xff08;一&#xff09;、单点交叉和两点交叉 一、遗传算法流程图 交叉过程即存在于上图的”交叉“&#xff08;crossover&#xff09;步骤中。 二、多点交叉 多点交叉的原理就是&#x…

腾讯云centos上安装docker

下面的操作是在root用户下操作的,如果非root用户在命令行前加上sudo 1. 系统及内核查看 操作系统&#xff1a;64位的CentOS 7或更新版本。内核版本&#xff1a;最低要求是3.10&#xff0c;推荐使用3.10或更高版本。 #查看内核版本 (base) [klfwjfweaVM-0-6-centos ~]$ uname…

ARM服务器在云手机中可以提供哪些支持

ARM服务器作为云手机的底层支撑&#xff0c;在很多社媒APP或者电商APP平台都有着很多看不见的功劳&#xff0c;可以说ARM扮演着至关重要的底层支持角色&#xff1b; 首先&#xff0c;ARM 服务器为云手机提供了强大的计算能力基础。云手机需要处理大量的数据和复杂的运算&#x…

uniapp自定义的下面导航

uniapp自定义的下面导航 看看效果图片吧 文章目录 uniapp自定义的下面导航 看看效果图片吧 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6aa0e964741d4dd3a58f4e86c4bf3247.png) 前言一、写组件、我这里就没有写组件了直接写了一个页面&#xff1f;总结 前言 在…

一文掌握Vue3:深度解读Vue3新特性、Vue2与Vue3核心差异以及Vue2到Vue3转型迭代迁移重点梳理与实战

每次技术革新均推动着应用性能与开发体验的提升。Vue3 的迭代进步体现在性能优化、API重构与增强型TypeScript支持等方面&#xff0c;从而实现更高效开发、更优运行表现&#xff0c;促使升级成为保持竞争力与跟进现代前端趋势的必然选择。本文深度解读Vue3 响应式数据data、生命…

Java Web学习笔记27——对话框、表单组件

常见组件对话框&#xff1a; Dialog对话框&#xff1a;在保留当前页面状态下&#xff0c;告知用户并承载相关操作。 dialogTableVisible: false 默认是不可见的。 在按钮属性中设置为true的意思&#xff0c;点击按钮的时候&#xff0c;才会true&#xff0c;对话框才会显示。 …

idm2024最新完美破解版免费下载 idm绿色直装版注册机免费分享 idm永久激活码工具

IDM 2024破解版重新开发了调度程序和MMS协议支持、重新设计和增强的下载引擎、与所有最新浏览器的独特高级集成、改进的工具栏以及大量其他改进和新功能&#xff0c;这一全新的更新&#xff0c;使得IDM下载器更加完美。值得一提的是&#xff0c;它可以借助油猴浏览器的脚本&…

Linux编译器-gcc或g++的使用

一.安装gcc/g 在linux中是不会自带gcc/g的&#xff0c;我们需要编译程序就自己需要安装gcc/g。 很简单我们使用简单的命令安装gcc&#xff1a;sudo yum install -y gcc。 g安装&#xff1a;sudo yum install -y gcc-c。 我们知道Windows上区分文件&#xff0c;都是使用文件…

ssm610学生社团管理系统+vue【已测试】

前言&#xff1a;&#x1f469;‍&#x1f4bb; 计算机行业的同仁们&#xff0c;大家好&#xff01;作为专注于Java领域多年的开发者&#xff0c;我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源&#xff1a; &#x1f469;‍&#x1f4bb; SpringBoot…

小熊家务帮day15-day17 预约下单模块(预约下单,熔断降级,支付功能,退款功能)

目录 1 预约下单1.1 需求分析1.1.1 业务流程1.1.2 订单状态 1.2 系统设计1.2.1 订单表设计1.2.2 表结构的设置 1.3 开发远程调用接口1.3.0 复习下远程调用的开发1.3.1 查询地址簿远程接口jzo2o-api工程定义接口Customer服务实现接口 1.3.2 查询服务&服务项远程接口jzo2o-ap…

运维 之 DNS域名解析

前言 我们每天打开的网站&#xff0c;他是如何来解析&#xff0c;并且我们怎么能得到网站的内容反馈的界面呢&#xff1f;那什么是DNS呢&#xff08;DNS&#xff08;DomainNameservice&#xff0c;域名服务&#xff0c;主要用于因特网上作为域名和IP地址相互映射&#xff09;那…

【iOS】MRC下的单例模式批量创建单例

单例模式的介绍和ARC下的单例请见这篇&#xff1a;【iOS】单例模式 目录 关闭ARC环境MRC下的单例ARC下的单例批量创建单例Demo 关闭ARC环境 首先关闭ARC环境&#xff0c;即打开MRC&#xff1a; 或是指定某特定目标文件为非ARC环境&#xff1a; 双击某个类文件&#xff0c;指定…

SpringBoot2+Vue3开发课程审核流程系统

SpringBoot2Vue3开发课程审核流程系统 简介 此系统实现了课程审核全流程功能并使用了Activiti7工作流技术&#xff0c;功能包含&#xff1a;课程管理、用户管理、流程定义、课程审核&#xff08;我的申请、我的代办、我的已办&#xff09; 功能介绍 课程管理 对课程信息的管…

C++的STL 中 set.map multiset.multimap 学习使用详细讲解(含配套OJ题练习使用详细解答)

目录 一、set 1.set的介绍 2.set的使用 2.1 set的模板参数列表 2.2 set的构造 2.3 set的迭代器 2.4 set的容量 2.5 set的修改操作 2.6 set的使用举例 二、map 1.map的介绍 2.map的使用 2.1 map的模板参数说明 2.2 map的构造 2.3 map的迭代器 2.4 map的容量与元…

API测试工具

apifox 微信扫描登录 不推荐&#xff1a; Download Postman

QT creator c动态链接库的创建与调用

QT creator c动态链接库的创建与调用 QT5.15.2 1.创建dll项目 确保两类型选择正确 2.选择MinGW 64-bit 3.点击完成 pro文件参考&#xff1a; QT - guiTEMPLATE lib DEFINES QT_DLL_DEMO_LIBRARYCONFIG c17# You can make your code fail to compile if it uses deprecat…

Flutter 使用ffigen生成ffmpeg的dart接口

Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频 第六章 桌面端使用texture_rgba_renderer渲染视频 第七章 使用ff…

以sqlilabs靶场为例,讲解SQL注入攻击原理【54-65关】

【Less-54】 与前面的题目不同是&#xff0c;这里只能提交10次&#xff0c;一旦提交超过十次&#xff0c;数据会重新刷新&#xff0c;所有的步骤需要重来一次。 解题步骤&#xff1a; 根据测试&#xff0c;使用的是单引号闭合。 # 判断字段的数量 ?id1 order by 3 -- aaa# …