了解“/linux-5.4.31/drivers/of/device.c”中的of_device_get_match_data()

1、打开“drivers/of/base.c”

#define of_prop_cmp(s1, s2) strcmp((s1), (s2))

/*如果s1小于s2,则返回值小于0。

如果s1大于s2,则返回值大于0。

如果s1等于s2,则返回值等于0。*/

//函数功能:根据所给的“设备树的节点np”和“properties名字”在设备树里查找是否有“properties名字”

//np是指向设备树的节点

//name是指向要查找的properties名字

//lenp用来返回properties名字的长度

static struct property *__of_find_property(const struct device_node *np,

   const char *name, int *lenp)

{

struct property *pp;

if (!np)return NULL;

for (pp = np->properties; pp; pp = pp->next)

{

if (of_prop_cmp(pp->name, name) == 0)

{ //如果pp->name等于name,则返回值等于0。

if (lenp) *lenp = pp->length;//保存properties名字的长度

break;

}

}

return pp;//返回property结构指针

}

const char *of_prop_next_string(struct property *prop, const char *cur)

{

const void *curv = cur;

if (!prop)return NULL;//如果prop=NULL,则返回NULL

if (!cur)return prop->value;//如果prop=NULL,则返回prop->value

curv += strlen(cur) + 1;//求cur字符串的长度,包括结束符;

if (curv >= prop->value + prop->length)//所给字符串的长度

return NULL;

return curv;

}

/*函数功能:根据name,在np指向的节点查找name所指向的字符串;返回属性名字的长度

保存在lenp中,并返回属性的指针值*/

static struct property *__of_find_property(const struct device_node *np,

   const char *name, int *lenp)

{

struct property *pp;

if (!np) return NULL;//如果np=NULL,则返回NULL

for (pp = np->properties; pp; pp = pp->next)

{ /*np->properties指向属性*/

if (of_prop_cmp(pp->name, name) == 0)

{

/*根据所给的“设备树的节点np”和“name所指向的名字”在设备树里查找是否有“name所指向的名字”*/

if (lenp) *lenp = pp->length;//返回属性名字的长度

break;

}

}

return pp;

}

/*根据所给的节点查找给定名字的属性

 * Find a property with a given name for a given node

 * and return the value.

 */

const void *__of_get_property(const struct device_node *np,

      const char *name, int *lenp)

{

struct property *pp = __of_find_property(np, name, lenp);

/*函数功能:根据name,在np指向的节点查找name所指向的字符串;返回属性名字的长度

保存在lenp中,并返回属性的指针值*/

return pp ? pp->value : NULL;

//如果pp!=NULL,则返回pp->value

}

//函数功能:如果根据所给的节点查找到了属性名为type,则返回1

static bool __of_node_is_type(const struct device_node *np, const char *type)

{

const char *match = __of_get_property(np, "device_type", NULL);

//根据所给的节点np查找device_type的属性,match=np->value

return np && match && type && !strcmp(match, type);

//np->valuetype相同,返回1

}

//检查节点是否匹配所给的“name”,匹配则返回1;

bool of_node_name_eq(const struct device_node *np, const char *name)

{

const char *node_name;

size_t len;

if (!np)return false;

node_name = kbasename(np->full_name);//从np->full_name中提取名字;

len = strchrnul(node_name, '@') - node_name;//计算节点名字的长度

return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);

//检查是否找到name所指向的字符串,匹配则返回1

}

#define INT_MAX 0x7fffffff

/**

函数功能:检查节点是否匹配所给的“compattypename”;

device: 指向节点的指针;

compat: compatible的缩写,要求匹配的字符串, 也可能是NULL或者是"";

type: 要求匹配的device_type, 也可能是NULL或者是"";

name: 要求匹配的节点名字, 也可能是NULL或者是"";

返回值为0,表示不匹配;返回值大于0,表示匹配;

 * 1. specific compatible && type && name

 * 2. specific compatible && type

 * 3. specific compatible && name

 * 4. specific compatible

 * 5. general compatible && type && name

 * 6. general compatible && type

 * 7. general compatible && name

 * 8. general compatible

 * 9. type && name

 * 10. type

 * 11. name

 */

static int __of_device_is_compatible(const struct device_node *device,

     const char *compat, const char *type, const char *name)

{

struct property *prop;

const char *cp;

int index = 0, score = 0;

/* Compatible匹配具有最高优先级 */

if (compat && compat[0])//如果compat!=NULL,且compat[0]>0,则执行

{

prop = __of_find_property(device, "compatible", NULL);

/*根据所给的“设备树的节点device”和“properties名字compatible”在设备树里查找是否有“compatible”;

返回值是property结构指针

*/

for (cp = of_prop_next_string(prop, NULL); cp;

     cp = of_prop_next_string(prop, cp), index++)

{

/*of_prop_next_string(prop, NULL)执行后cp=prop->value;*/

/*of_prop_next_string(prop, cp)cp=cp+strlen(cp) + 1;指向下一个prop->value*/

if (of_compat_cmp(cp, compat, strlen(compat)) == 0)

{ /*根据所给的“设备树的节点cp”和“compat所指向的名字”在设备树里查找是否有“compat所指向的名字”*/

score = INT_MAX/2 - (index << 2);

break;

}

}

if (!score)return 0;

}

/*匹配type比匹配的name的优先级要高;Matching type is better than matching name */

if (type && type[0])//如果type!=NULL,且type[0]>0,则执行

{

if (!__of_node_is_type(device, type))return 0;

//如果根据所给的device节点查找到了属性名为type,则返回1;

score += 2;

}

/* 要匹配的名字,Matching name is a bit better than not */

if (name && name[0])//如果name!=NULL,且name[0]>0,则执行

{

if (!of_node_name_eq(device, name))return 0;

        //of_node_name_eq()检查节点是否匹配所给的“name”,匹配则返回1;

score++;

}

return score;

}

static

const struct of_device_id *__of_match_node(const struct of_device_id *matches,

   const struct device_node *node)

{

const struct of_device_id *best_match = NULL;

int score, best_score = 0;

if (!matches)

return NULL;

for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {

score = __of_device_is_compatible(node, matches->compatible,

  matches->type, matches->name);

       /*检查节点是否匹配所给的“compattypename”;*/

if (score > best_score) {

best_match = matches;

best_score = score;

}

}

return best_match;

}

/**判断device_node是否具有匹配的of_match结构

 * of_match_node - Tell if a device_node has a matching of_match structure

 * @matches: array of of device match structures to search in

 * @node: the of device structure to match against

 *

 * Low level utility function used by device matching.

 */

const struct of_device_id *of_match_node(const struct of_device_id *matches,

 const struct device_node *node)

{

const struct of_device_id *match;

unsigned long flags;

raw_spin_lock_irqsave(&devtree_lock, flags);

match = __of_match_node(matches, node);

raw_spin_unlock_irqrestore(&devtree_lock, flags);

return match;

}

2、打开“drivers/of/device.c”

const struct of_device_id *of_match_device(const struct of_device_id *matches,

   const struct device *dev)

{

if ((!matches) || (!dev->of_node))

return NULL;

return of_match_node(matches, dev->of_node);

/*使用of_match_node函数查找匹配的设备ID*/

}

const void *of_device_get_match_data(const struct device *dev)

{

const struct of_device_id *match;

match = of_match_device(dev->driver->of_match_table, dev);

if (!match)

return NULL;

return match->data;

}

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

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

相关文章

Python 鼠标轨迹 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

React受控组件的核心原理与实战精要

在 React 中&#xff0c;受控组件&#xff08;Controlled Component&#xff09; 是一种重要的模式&#xff0c;用于通过组件的状态来管理表单元素的值。这种模式不仅确保了数据的一致性和可预测性&#xff0c;还便于与其他功能&#xff08;如验证和格式化&#xff09;集成。本…

MapReduce是什么?

MapReduce 是一种编程模型&#xff0c;最初由 Google 提出&#xff0c;旨在处理大规模数据集。它是分布式计算的一个重要概念&#xff0c;通常用于处理海量数据并进行并行计算。MapReduce的基本思想是将计算任务分解为两个阶段&#xff1a;Map 阶段和 Reduce 阶段。 Map 阶段&a…

?和.和*在正则表达式里面的区别

在正则表达式中&#xff0c;?、. 和 * 是三种非常重要的元字符&#xff0c;它们各自有不同的功能和用途&#xff0c;以下是它们的区别&#xff1a; ?&#xff08;问号&#xff09; 功能&#xff1a;表示前面的元素&#xff08;字符、字符集、分组等&#xff09;是可选的&…

DevOps的个人学习

一、DevOps介绍 软件开发最初是由两个团队组成&#xff1a; 开发团队&#xff1a;负责设计和构建系统。运维团队&#xff1a;负责测试代码后部署上线&#xff0c;确保系统稳定安全运行。 这两个看似目标不同的团队需要协同完成一个软件的开发。DevOps整合了开发与运维团队&a…

数据库系统概论的第六版与第五版的区别,附pdf

我用夸克网盘分享了「数据库系统概论第五六版资源」&#xff0c;点击链接即可保存。 链接&#xff1a;https://pan.quark.cn/s/21a278378dee 第6版教材修订的主要内容 为了保持科学性、先进性和实用性&#xff0c;在第5版教材基础上对全书内容进行了修改、更新和充实。 在科…

攻防世界32 very_easy_sql【SSRF/SQL时间盲注】

不太会&#xff0c;以后慢慢看 被骗了&#xff0c;看见very_easy就点进来了&#xff0c;结果所有sql能试的全试了一点用都没有 打开源代码发现有个use.php 好家伙&#xff0c;这是真的在考sql吗...... 制作gopher协议的脚本&#xff1a; import urllib.parsehost "12…

11vue3实战-----封装缓存工具

11vue3实战-----封装缓存工具 1.背景2.pinia的持久化思路3.以localStorage为例解决问题4.封装缓存工具 1.背景 在上一章节&#xff0c;实现登录功能时候&#xff0c;当账号密码正确&#xff0c;身份验证成功之后&#xff0c;把用户信息保存起来&#xff0c;是用的pinia。然而p…

协议-WebRTC-HLS

是什么&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09; 实现 Web 浏览器和移动应用程序之间通过互联网直接进行实时通信。允许点对点音频、视频和数据共享&#xff0c;而无需任何插件或其他软件。WebRTC 广泛用于构建视频会议、语音通话、直播、在线游…

vscode设置保存时自动缩进和格式化

参考博客 如何在 VSCode 中自动缩进你的代码 | Linux 中国 省流 使用 Ctrl Shift P 来打开命令模式&#xff0c;搜索 Open User Settings 并按下回车你需要搜索 Auto Indent&#xff0c;并在 “编辑器&#xff1a;自动缩进(Editor: Auto Indent)” 中选择 “全部(Full)”P…

LSSVM最小二乘支持向量机多变量多步光伏功率预测(Matlab)

代码下载&#xff1a;LSSVM最小二乘支持向量机多变量多步光伏功率预测&#xff08;Matlab&#xff09; LSSVM最小二乘支持向量机多变量多步光伏功率预测 一、引言 1.1、研究背景与意义 随着全球能源危机和环境问题的日益严重&#xff0c;可再生能源的开发利用成为了世界各国…

从家庭IP到全球网络资源的无缝连接:Cliproxy的专业解决方案

数字化时代&#xff0c;家庭IP作为个人或家庭接入互联网的门户&#xff0c;其重要性日益凸显。然而&#xff0c;要实现从家庭IP到全球网络资源的无缝连接&#xff0c;并享受高效、安全、稳定的网络访问体验&#xff0c;往往需要借助专业的代理服务。Cliproxy&#xff0c;作为业…

ubuntu 22.04 安装 cuda sdk 11.8

ubuntu 22.04 安装 cuda sdk 11.8 linux kernel 版本太高的问题 主要思路是先安装 nv 显卡驱动&#xff0c;这会同时安装 kmd driver 然后安装 cuda sdk 11.x 时不安装 kernel driver 下载 display driver 搜索 display driver https://www.nvidia.com/en-us/drivers/ 选择比…

Day.23

leetcode 413.等差数列划分 问题&#xff1a;如果一个数列 至少有三个元素 &#xff0c;并且任意两个相邻元素之差相同&#xff0c;则称该数列为等差数列。给你一个整数数组 nums &#xff0c;返回数组 nums 中所有为等差数组的 子数组 个数。 子数组 是数组中的一个连续序列…

leetcode 做题思路快查

58. 最后一个单词的长度 考虑从字符串size() - 1处倒序的定义两个指针&#xff1b;多的空格用while(j > 0 && s[j] ) j--跳过&#xff1b; 考虑"a" "_"这两个场景 s45. 跳跃游戏 II 思路&#xff1a;动态规划&#xff0c;f[i] 0...i-1跳到…

Ollama 部署 DeepSeek-R1 及Open-WebUI

Ollama 部署 DeepSeek-R1 及Open-WebUI 文章目录 Ollama 部署 DeepSeek-R1 及Open-WebUI〇、说明为什么使用本方案 一、 安装Ollama1、主要特点&#xff1a;2、安装3、验证 二、Ollama 部署 DeepSeek1、部署2、模型选用3、Ollama 常用命令4、Ollama模型默认存储路径 安装open-w…

feign Api接口中注解问题:not annotated with HTTP method type (ex. GET, POST)

Bug Description 在调用Feign api时&#xff0c;出现如下异常&#xff1a; java.lang.IllegalStateException: Method PayFeignSentinelApi#getPayByOrderNo(String) not annotated with HTTPReproduciton Steps 1.启动nacos-pay-provider服务&#xff0c;并启动nacos-pay-c…

网络计算机的相关概念整理

网络计算机的五个组成部分 单个计算机是无法进行通信的。所以需要借助网络。 下面介绍一些在网络里常见的设备。 一、服务器 服务器是在网络环境中提供计算能力并运行软件应用程序的特定IT设备 它在网络中为其他客户机&#xff08;如个人计算机、智能手机、ATM机等终端设备&…

Python微博动态爬虫

本文是刘金路的《语言数据获取与分析基础》第十章的扩展&#xff0c;详细解释了如何利用Python进行微博爬虫&#xff0c;爬虫内容包括微博指定帖子的一级评论、评论时间、用户名、id、地区、点赞数。 整个过程十分明了&#xff0c;就是用户利用代码模拟Ajax请求&#xff0c;发…

[NKU]C++安装环境 VScode

bilibili安装教程 vscode 关于C/C的环境配置全站最简单易懂&#xff01;&#xff01;大学生及初学初学C/C进&#xff01;&#xff01;&#xff01;_哔哩哔哩_bilibili 1安装vscode和插件 汉化插件 ​ 2安装插件 2.1 C/C 2.2 C/C Compile run ​ 2.3 better C Syntax ​ 查看已…