Linux驱动入门(6.1)LED驱动---设备树

2023-11-01

前言

(1)在韦东山Linux驱动入门实验班(5)LED驱动—驱动分层和分离,平台总线模型我们已经讲解了如何将驱动程序和硬件程序进行剥离。但是大佬们感觉这样还不行,他们认为要专门弄一个结构存储硬件信息,而不是用c文件存储。于是,大佬们就发明了设备树进行存储硬件信息。
(2)代码仓库:gitee仓库github仓库
(3)注意:大家下载我仓库里面的代码再阅读本文会跟好理解一点。我仓库里面的代码依旧加上了详细的注释,觉得本文过于冗余。可以看我仓库代码和正点原子的文档学习。
(4)我这里将会使用BCompare软件进行文件对比,方便各位理解。

不同点

不同点1 — platform_driver配置不同

(1)同样,一个驱动程序还是需要从module_init()这个宏开始看起,然后网上爬,我们会发现platform_driver结构体有一个细微的区别。
(2)platform_driver.driver里面我们增加了一个of_match_table变量,led_dtb。这个是用于和设备树进行匹配的。关于驱动程序和设备匹配规则不太明白的同学,建议看一下 Linux驱动与设备的匹配规则
(3)我们在of_match_table变量中需要传入const struct of_device_id类型的数组。这里里面的of_device_id结构体中的compatible值要和设备树里面的compatible 名字是一模一样的。否则无法匹配成功。

/*   在dts文件下增加这几行  */
/{
    test1:test_device_tree{
           compatible = "test_compatible";
           gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
        };
}

在这里插入图片描述

不同点2 — 存放设备信息的结构体不同

(1)如果驱动和设备匹配上了,就会触发probe函数。在这个函数里面我们需要获得设备信息。如果是设备树,使用device_node指针可以获得。如果是c文件中的设备信息,使用resource结构体指针可以获得数据。
(2)如果匹配上了设备树np将会指向这个设备树文件。否则np将会是一个空指针。

struct device_node *np = pdev->dev.of_node;  //设备树中
struct resource *led_resource;  //c文件中

在这里插入图片描述

不同点3 — 获取gpio数量的方式不同

(1)在设备树中,直接调用of_gpio_count(np)可以获得gpio的数量。
(2)而在C文件中,有两种方式可以获得设备信息。

//设备树中统计的设备的 GPIO 数量
count = of_gpio_count(np); 
//C文件中获取GPIO数量的两种方法
count = pdev->num_resources; //这个不会区分GPIO的flag

while (1)  //这个可以获得指定flag的GPIO数量
{
	/* 下面这9行,是用于统计有多少个GPIO的
	 * dev:一个指向 platform_device 结构的指针,表示要获取资源信息的设备。
	 * type:一个无符号整数,表示要获取的资源类型。在 Linux 内核中,资源类型使用常量来表示,
	        例如 IORESOURCE_MEM 表示内存资源,IORESOURCE_IRQ 表示中断资源等。你可以根据需要选择适当的资源类型。
	 * num:一个无符号整数,表示要获取的资源的索引号。在一个设备中可能存在多个相同类型的资源,通过索引号可以区分它们。
	 * 返回值:返回一个指向 resource 结构的指针,表示获取到的资源信息。
	           resource 结构包含了资源的起始地址、大小等信息。如果没有找到指定的资源,函数将返回 NULL。
	*/
	led_resource = platform_get_resource(pdev, IORESOURCE_IRQ, count);
	if (led_resource)
	{
		count++;
	}
	else
	{
		break;
	}
}

在这里插入图片描述

不同点4 — 获取引脚号的方式不同

(1)
<1>在设备树中,直接调用of_get_gpio()可以获得gpios的数据,然后并且将他转换为引脚号。
<2>例如本文中的<&gpio5 3 GPIO_ACTIVE_HIGH>,他会调用desc_to_gpio这个函数将gpio5 3转换为引脚号131。
(2)在c文件中,获取引脚信息需要调用platform_get_resource()函数获得platform_device.resource结构体,然后调用led_resource->start,就可以获得引脚号了。不过这个引脚号需要你本人来进行计算。所以相对来说麻烦一点。

//设备树
gpios[i].gpio = of_get_gpio(np, i);   //获得gpio信息

//c文件中
led_resource = platform_get_resource(pdev, IORESOURCE_IRQ, i);  //从节点里面取出第i项
if(led_resource==NULL)
{
	printk("platform_get_resource is flaut\r\n");
}
printk("platform_get_resource is ok\r\n");
gpios[i].gpio = led_resource->start;  //将需要操作的IO号传递给gpios[i].gpio

不同点5 — 获取引脚名字的方式不同

(1)说实话,其实也差不多。都是一个结构体指针指向name变量。为了方便新手理解,还是当成不同来处理算了。

//设备树
sprintf(gpios[i].name, "%s", np->name);  //将设备树中的节点名字传递给gpios[i].name

//c文件
sprintf(gpios[i].name, "%s", pdev->name); //将platform_device.resource.name传递给gpios[i].name
		

OF函数介绍

(1)Linux的设备树起源于OpenFirmware,OF。所以与设备树相关的函数前缀都有OF,也就是OF函数。
(2)我们驱动如何想获取设备树的信息,就需要调用OF函数。OF函数需要先找到节点,然后才可以获取属性。所以我这里将会分为获得节点和获得属性两部分讲解。

使用OF函数获得节点

of_find_node_by_name()函数

(1)根据名字查找节点

/* 作用 : 查找设备树中特定节点的函数
 * 传入参数 : 
     * from : 指向一个起始节点,该函数从这个节点开始向上遍历设备树,查找匹配名称的节点。
     * name : 要查找的节点的名称
 * 返回值 : 如果找到了匹配名称的节点,函数将返回该节点的指针(struct device_node*)。否则返回NULL。
*/
struct device_node *of_find_node_by_name(struct device_node *from,const char *name);

/*------- 示例 --------*/
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为led_test_compatible
*/
of_find_node_by_name(NULL,"led_test_compatible");

of_find_node_by_path()函数

(1)这个是根据路径查找对应节点

/* 作用 : 根据节点的路径查找节点
 * 传入参数 : 
     * path : 一个以斜杠(/)分隔的字符串,表示设备树中从根节点到目标节点的路径
 * 返回值 : 如果找到了匹配名称的节点,函数将返回该节点的指针(struct device_node*)。否则返回NULL。
*/
of_find_node_by_path(const char *path);

/*------- 示例 --------*/
/* "/topeet/myled" : 在根节点下的topeet节点中,找到myled节点
*/
of_find_node_by_path("/topeet/myled");

在这里插入图片描述

of_get_parent()函数

(1)获取指定节点的父节点

/* 作用 : 获取指定节点的父节点
 * 传入参数 : 
     * node : 要获得哪个节点的父节点
 * 返回值 : 成功返回查找到的父节点,失败返回NULL
*/
struct device_node *of_get_parent(const struct device_node *node);

/*------- 示例 --------*/
struct device_node * mydevice_node;
/* "/topeet/myled" : 在根节点下的topeet节点中,找到myled节点
*/
mydevice_node = of_find_node_by_path("/topeet/myled");
printk("mydevice node is %s n",mydevice_node->name); //打印出myled
/* mydevice_node : 获得mydevice_node的父节点
*/
mydevice_node = of_get_parent(mydevice_node);
printk("mydevice bab node is %s n",mydevice_node->name); //打印出topeet

of_get_next_child()函数

(1)获取指定节点的父节点

/* 作用 : 获取指定节点的父节点
 * 传入参数 : 
     * node : 父节点
     * prev : 从哪个子节点开始查找下一个子节点,设置为NULL,表示从第一个节点开始
 * 返回值 : 成功返回查找到的节点,失败返回NULL
*/
struct device_node *of_get_next_child(const struct device_node *node,
	struct device_node *prev)

/*------- 示例 --------*/
struct device_node * mydevice_node;
/* "/topeet/myled" : 在根节点下的topeet节点中,找到myled节点
*/
mydevice_node = of_find_node_by_path("/topeet/myled");
printk("mydevice node is %s n",mydevice_node->name); //打印出myled

/* mydevice_node : 获得mydevice_node的父节点
*/
mydevice_node = of_get_parent(mydevice_node);
printk("mydevice bab node is %s n",mydevice_node->name); //打印出topeet

/* mydevice_node : 获得mydevice_node的子节点
 * NULL : 从第一个节点开始
*/
mydevice_node = of_get_next_child(mydevice_node,NULL);
printk("mydevice child node is %s n",mydevice_node->name); //打印出myled

of_find_compatible_node()函数

(1)通过device_type和compatible属性来查找指定节点

/* 作用 : 通过device_type和compatible属性来查找指定节点
 * 传入参数 : 
     * from : 从哪个节点开始查找,如果是NULL表示从根节点开始查找
     * type : 要查找的节点的device_type属性的属性值,可以为NULL,代表忽略device_type属性
     * compatible: 要查找的节点对应的compatible属性列表
 * 返回值 : 成功返回查找到的节点,失败返回NULL
*/
of_find_compatible_node(struct device_node *from, const char *type, const char *compat);

/*------- 示例 --------*/
struct device_node * mydevice_node;
/* NULL : 从根节点开始查找
 * NULL : 表示要查找的节点没有device_type属性,或者是忽略查找他的device_type属性
 * "my_devicetree" : 要查找的节点compatible属性叫做my_devicetree
*/
mydevice_node = of_find_compatible_node(NULL,NULL,"my_devicetree");

使用OF函数获得属性

of_find_property()函数

(1)查找节点下指定的属性

/* 作用 : 查找节点下指定的属性
 * 传入参数 : 
     * np : 查找的节点
     * name : 要查找的属性的属性名
     * lenp : 属性值的字节数
 * 返回值 :  成功返回查找的属性,失败返回NULL
*/
struct property *of_find_property(const struct device_node *np,
				  const char *name,
				  int *lenp)
/*------- 示例 --------*/
struct device_node * mydevice_node;
struct property *my_property;
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为led_test_compatible
*/
mydevice_node = of_find_node_by_name(NULL,"led_test_compatible");
my_property = of_find_property(mydevice_node,"compatible",&size);

of_property_count_elems_of_size函数

(1)获取属性中元素的数量

/* 作用 : 获取属性中元素的数量
 * 传入参数 : 
     * np : 设备节点
     * propname : 需要获取那个属性的元素数量
     * elem_size : 单个元素尺寸
 * 返回值 :  成功返回元素的数量
*/
int of_property_count_elems_of_size(const struct device_node *np,
				const char *propname, int elem_size)
/*------- 示例 --------*/
struct device_node * mydevice_node;
int num;
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为my_devicetree
*/
mydevice_node = of_find_node_by_name(NULL,"my_devicetree");
/* mydevice_node : 在mydevice_node 设备节点中查找
 * "reg" : 需要获取reg属性的元素数量
 * 4 : 元素是4个字节
*/
num = of_property_count_elems_of_size(mydevice_node,"reg",4);
printk("reg num is %d\n",num); //因为reg中有两个元素,所以打印2

在这里插入图片描述

of_property_read_uxx_index()函数

(1)这种类型的函数有2种:of_property_read_u32_index() 函数;of_property_read_u64_index() 函数;
(2)这里分别代表要读取的数据是多少个bit。示例如下

/* 作用 : 获取属性中元素的数量
 * 传入参数 : 
     * np : 设备节点
     * propname : 要读取的属性名字
     * index : 读取这个属性下第几个值,index从0开始
     * out_value : 读到的值
 * 返回值 :  成功返回0
*/
int of_property_read_u32_index(const struct device_node *np,
				       const char *propname,
				       u32 index, u32 *out_value)
/*------- 示例 --------*/
struct device_node * mydevice_node;
u32 value_u32;
u64 value_u64;
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为my_devicetree
*/
mydevice_node = of_find_node_by_name(NULL,"my_devicetree");
/* mydevice_node : 在mydevice_node 设备节点中查找
 * "reg" : 需要读取的reg属性
 * 0 : 从第0个元素开始读取
 * value_uxx : 读取到的数据存放在这个变量种
*/
of_property_read_u32_index(mydevice_node,"reg",0,&value_u32);
of_property_read_u64_index(mydevice_node,"reg",0,&value_u64);
printk("value u32 is 0x%x\n",value_u32);  
printk("value u64 is 0x%llx\n",value_u64);

在这里插入图片描述
在这里插入图片描述

of_property_read_variable_uxx_array()函数

(1)这种类型的函数有4种:of_property_read_variable_u8_array() 函数;of_property_read_variable_u16_array() 函数;of_property_read_variable_u32_array() 函数;of_property_read_variable_u64_array() 函数;
(2)这里表示读取的数组,是什么类型的数组。示例如下

/* 作用 : 获取属性中元素的数量
 * 传入参数 : 
     * np : 设备节点
     * propname : 要读取的属性名字
     * out_values : 读取到的数组值,分别为u8、u16、u32、u64
     * sz_min : 数组最小值
     * sz_max : 数组最大值
 * 返回值 :  成功返回0
*/
int of_property_read_variable_u32_array(const struct device_node *np,
			       const char *propname, u32 *out_values,
			       size_t sz_min, size_t sz_max)
/*------- 示例 --------*/
struct device_node * mydevice_node;
u32 out_value[2];
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为my_devicetree
*/
mydevice_node = of_find_node_by_name(NULL,"my_devicetree");
/* mydevice_node : 在mydevice_node 设备节点中查找
 * "reg" : 需要读取的reg属性
 * out_value : 读取到的数组数据存储在这个里面
 * 1 : 读取的数组最少1个元素
 * 2 : 读取的数组最多2个元素
*/
of_property_read_variable_u32_array(mydevice_node, "reg" ,out_value,1,2);
printk("out value[0] is 0x%x\n",out_value[0]); //打印0xfdd6000
printk("out value[1] is 0x%x\n",out_value[1]); //打印0x4

在这里插入图片描述

of_property_read_string()函数

(1)读取属性中的字符串

/* 作用 : 读取属性中的字符串
 * 传入参数 : 
     * np : 设备节点
     * propname : 要读取的属性名字
     * out_string : 读取到的字符串
 * 返回值 :  成功返回0
*/
int of_property_read_string(const struct device_node *np, const char *propname,
				const char **out_string)
/*------- 示例 --------*/
struct device_node * mydevice_node;
const char *value_compatible;
/* NULL : 表示从根节点开始查找
 * name : 节点的compatible名字为my_devicetree
*/
mydevice_node = of_find_node_by_name(NULL,"my_devicetree");
/* mydevice_node : 在mydevice_node 设备节点中查找
 * "compatible" : 需要读取的compatible属性
 * value_compatible : 读取到compatible属性的字符串
*/
of_property_read_string(mydevice_node,"compatible",&value_compatible);
printk("compatible value is %s\n",value_compatible); //打印my_devicetree

在这里插入图片描述

总结

设备树其实就是将设备信息从原来存放在c文件中,变成一种树形结构来存储,然后是dts文件存储。这个能够很好的将驱动文件与设备文件剥离。实现真正的脱离硬件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux驱动入门(6.1)LED驱动---设备树 的相关文章

  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • 如何使用 bash 脚本关闭所有终端,在每个终端中有效地按 Ctrl+Shift+Q

    我经常打开许多终端 其中一些正在运行重要的进程 例如服务器 而另一些则没有运行任何东西并且可以关闭 如果您按 重要 则会弹出确认提示Cntrl Shift Q在其中 如下所示 我想要一个 bash 脚本 它可以关闭所有终端 但将 重要 终端
  • gnome-terminal 新选项卡,使用别名作为要执行的命令

    我已经创建了一个别名 bashrc文件如下 alias myproject cd Desktop myproject 当我重新启动终端时保存文件后 输入myproject带我到项目目录 但是当我尝试使用别名作为新的命令参数时gnome te
  • 如何阅读shell命令的源代码?

    我想阅读编写linux命令的实际源代码 我已经获得了一些使用它们的经验 现在我认为是时候与我的机器进行更深层次的交互了 我在这里找到了一些命令http directory fsf org wiki GNU http directory fs
  • 如何使用ffmpeg重叠和合并多个音频文件?

    我正在尝试将多个音频文件合并到一个文件中 但我可以使用以下命令来连接 而不是连接 ffmpeg v debug i file1 wav i file2 wav i file3 wav filter complex 0 0 concat n
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • sqlite 插入需要很长时间

    我正在将不到 200 000 行插入到 sqlite 数据库表中 我只是在终端中通过 sqlite3 使用一个非常简单的 sql 文件 我打赌它已经运行了至少 30 分钟 这是正常现象还是我应该关闭该过程并尝试不同的方法 sqlite中的插
  • Linux 中的电源管理通知

    在基于 Linux 的系统中 我们可以使用哪些方法 最简单的方法 来获取电源状态更改的通知 例如 当计算机进入睡眠 休眠状态等时 我需要这个主要是为了在睡眠前保留某些状态 当然 在计算机唤醒后恢复该状态 您只需配置即可获得所有这些事件acp
  • 为什么 ld 无法从 /etc/ld.so.conf 中的路径找到库?

    我想添加 opt vertica lib64进入系统库路径 所以我执行以下步骤 1 添加 opt vertica lib64 into etc ld so conf 然后运行ldconfig 2 检查 bash ldconfig p gre
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • 无关的库链接

    我有一个可能有点愚蠢的问题 因为我很确定我可能已经知道答案了 假设你有静态库A 动态共享库B和你的linux下的程序C 假设库 A 调用库 B 中的函数 并且您的程序调用库 A 中的函数 现在假设 C 在 A 中调用的所有函数都不使用 B
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • 操作系统什么时候清除进程的内存

    进程在某些操作系统上成功或异常终止 操作系统何时决定擦除分配给该进程的内存 数据 代码等 在退出时或当它想为新进程分配内存时 这个清除内存分配过程在所有操作系统 winXP Win7 linux Mac 上都相同吗 据我了解 页表具有该进程
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • gentoo crontab:为什么这个简单的 crontab 不起作用?

    我使用 GENTOO 发行版 crontab e 35 12 root php5 home www cron php 当我手动运行时 php5 php5 home www cron php 这有效 它向我发送了一封电子邮件 然后我检查日期
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将

随机推荐

  • 【转】svn详解

    转自 svn status详解 世界 太精彩 博客园 svn 是在提交前查看本地文本和版本库里面的文件的区别 返回值有许多种具体含义如下 L abc c svn已经在 svn目录锁定了abc c M bar c bar c的内容已经在本地修
  • python+pyqt5设置窗体图标和任务栏图标及窗体标题的方法

    本次设置窗体标题只用了一种方法 在进行窗体实例化后window Window 使用setWindowTitle str 命令 在主程序中的设置命令如下所示 if name main QApplication setAttribute Qt
  • lab4

    这一个lab主要学习进程管理和进程通讯 come on 好好学习 PART A 多处理器支持 Exercise 1 void mmio map region physaddr t pa size t size Where to start
  • 18虚幻4【UE4】 中场景中的N个actor赋予随机颜色

    问题 现在1000个静态网格体要附上随机颜色的材质 难道我们要写1000中材质 然后附上去吗 一 思路 获取场景中物体 创建材质实例 修改材质参数 通过get actors with tag也好 通过get actors of class也
  • 51单片机 IIC OLED屏幕驱动+Proteus仿真+实物验证示例程序

    51单片机 IIC OLED屏幕驱动 Proteus仿真 实物验证示例程序 Proteus仿真效果 注意点击运行仿真后 图像刷新出来比较慢 示例主程序 include REG51 h include oled h include bmp h
  • QT获取mysql数据库驱动步骤记录-版本QT_5.12.5-附精华链接

    首先先检查自己的QT已经加载的数据库版本 qDebug lt
  • ARM架构的外部中断介绍(S5PV210芯片)

    1 外部中断介绍 1 中断源的划分 内部中断和外部中断 所谓内部中断和外部中断 是根据中断源来自Soc内部还是外部 1 比如串口 定时器等都是Soc内部自带的 所以触发的中断都是内部中断 2 给Soc外接一个烟雾报警器 通过GPIO引脚和S
  • 关于移动端H5使用xhr上传文件

    首先我是用的是uniapp框架 所以以下内容皆以此未前提 我是第一次用uniapp 所以有些地方也不太熟悉 比如在写h5时 页面上的input的type写成file时页面上没有效果 查看官方文档后知道 需要使用js 插入一个input标签
  • Go语言学习(八)-- Gin入门

    Gin 是一个 Go Golang 编写的轻量级 http web 框架 运行速度非常快 Gin 最擅长的就是 Api 接口的高并发 如果项目的规模不大 业务相对简单 这个时候我们 也推荐您使用 Gin 当某个接口的性能遭到较大挑战的时候
  • js逆向实战案例集目录

    一 js逆向基础篇 js逆向之字体加密 js逆向webpack篇 某电商网站 拼xx js逆向基础篇 某房地产网站 登录 js逆向基础篇 某音乐网站 xx音乐 js逆向之猿人学 反混淆刷题平台第一题 手把手教学 js逆向验证码篇之某程 智能
  • react 创建sass router mobx项目

    尽量不要再vscode中安装依赖推荐使用gitbash 创建项目第一步 基本搭建 git 在创建之前 需要有一个git 仓库 我们之后要把项目搭建到git 中 node版本 查看node 版本 node v v14 15 3 为了保证同步
  • CUDA Vector Add Test 2048x1024

    1 include cuda runtime h CUDAVectorAdd cu 2 include device launch parameters h 3 include IML PrecisionTimer h 4 5 includ
  • 【笔记】Git及Github使用

    目录 Git概述及安装 Git常用命令 设置用户签名 姓名和邮箱地址 gitconfig 初始化本地库 查看本地库状态 本地文件添加到暂存区 提交本地库 形成历史版本 修改文件 历史版本信息 版本穿梭 回溯历史版本 查看当前本地库中所有文件
  • canvas清空画布方法

    1 最简单的方法 由于canvas每当高度或宽度被重设时 画布内容就会被清空 因此可以用以下方法清空 function clearCanvas span style font family none span var c document
  • mysql 存储引擎 原理_【MySQL—原理】体系结构和存储引擎

    在数据库领域中有两个词很容易混淆 这就是 数据库 database 和 实例 instance 作为常见的数据库术语 这两个词的定义如下 数据库 物理操作系统文件或其他形式文件类型的集合 实例 数据库管理程序 MySQL数据库由后台线程以及
  • 【狂神】MySQL - 连表查询 Join On 详解

    1 连表查询详解 市面上有 7 种连表查询 总共归为三大类 左查询 LEFT JOIN 以左表为基准 右查询 RIGHT JOIN 以右表为基准 交叉查询 INNER JOIN 查询两表都有的数据 操作 描述 inner join 如果表中
  • ajax嵌套的场景有哪些,ajax嵌套

    一 ajax嵌套ajax 传说中的嵌套金字塔 以及这种方式只能串联发起ajax请求 function getDataFun ajax url equip rank type GET dataType jsonp success functi
  • Qt之键盘事件无法响应问题

    Qt之键盘事件无法响应问题 概述 代码 over 文末一句话 概述 新公司的加班第一天 在调试公司项目代码时发现个小问题 鼠标 键盘事件都已写好 但是键盘事件无效无法进入断点 接来下去查文档并没有查到相关说明 翻阅百度翻到如下代码 并进行测
  • 配置文件文档

    Tranquilpeak Version 0 5 3 BETA Author Thibaud Lepr tre I STRONGLY recommend you to use a CDN to speed up loading of pag
  • Linux驱动入门(6.1)LED驱动---设备树

    前言 1 在韦东山Linux驱动入门实验班 5 LED驱动 驱动分层和分离 平台总线模型我们已经讲解了如何将驱动程序和硬件程序进行剥离 但是大佬们感觉这样还不行 他们认为要专门弄一个结构存储硬件信息 而不是用c文件存储 于是 大佬们就发明了