原创 写代码的篮球球痴 嵌入式Linux 2020-05-27

收录于话题

#Linux

130个

前言

今天在一个群里面看到的一个朋友提交,说of_property_read_string 这个函数有两个定义,到底是用了哪个呢?

所以这篇文章就说下这个函数。

函数引用的头文件

引用的头文件位置在

\kernel-4.4\include\linux\of.h

其中一个是

extern int of_property_read_string(struct device_node *np,
  const char *propname,
  const char **out_string);

还有一个是

static inline int of_property_read_string(struct device_node *np,
 const char *propname,
 const char **out_string)
{
return -ENOSYS;
}

但是并不是两个都用到,他们用了一个宏  CONFIG_OF 来选择

CONFIG_OF 宏有什么用?

这个宏的解释是

Open Firmware. This was invented long time ago when Apple was producing laptops based on PowerPC CPUs. Openfirmware provides a good description of the devices connected to the platform. In Linux kernel the part that works with device data is called Device Tree (DT). More details in theUsage model.

他的作用是

Openfirmware provides a good description of the devices connected to the platform

他提供了一种更好的方式来连接设备和驱动。

他是名字是

called Device Tree (DT)

DTS,那很明显了,开了这个宏,就表示使用了DTS设备树的方式来连接设备和驱动程序。

of_property_read_string 函数本体

函数位置

"./drivers/of/base.c"

函数原型

/**
* of_property_read_string - Find and read a string from a property
* @np:         device node from which the property value is to be read.
* @propname:   name of the property to be searched.
* @out_string: pointer to null terminated return string, modified only if
*              return value is 0.
*
* Search for a property in a device tree node and retrieve a null
* terminated string value (pointer to data, not a copy). Returns 0 on
* success, -EINVAL if the property does not exist, -ENODATA if property
* does not have a value, and -EILSEQ if the string is not null-terminated
* within the length of the property data.
*
* The out_string pointer is modified only if a valid string can be decoded.
*/
int of_property_read_string(struct device_node *np, const char *propname,
                               const char **out_string)
{
       struct property *prop = of_find_property(np, propname, NULL);
       if (!prop)
               return -EINVAL;
       if (!prop->value)
               return -ENODATA;
       if (strnlen(prop->value, prop->length) >= prop->length)
               return -EILSEQ;
       *out_string = prop->value;
       return 0;
}
EXPORT_SYMBOL_GPL(of_property_read_string);

函数的作用:

返回propname对应dts节点对应的值。

使用方式:

传入np,就是设备树的节点,然后返回 "clock-output-names" 字符串对应的值,存入clk_name 里面。

of_property_read_string 函数剖析of_property_read_string 剖析~_嵌入式
int of_property_read_string(struct device_node *np, const char *propname,
                               const char **out_string)
{
       struct property *prop = of_find_property(np, propname, NULL);
       if (!prop)
               return -EINVAL;
       if (!prop->value)
               return -ENODATA;
       if (strnlen(prop->value, prop->length) >= prop->length)
               return -EILSEQ;
       *out_string = prop->value;
       return 0;
}
EXPORT_SYMBOL_GPL(of_property_read_string);
  • of_find_property 这个是找到这个dts节点,怎么找,可以再去这个函数分析一下。
  • strnlen功能「获取字符串实际字符个数,不包括结尾的'\0';如果实际个数 <= 第二个参数,则返回字符串实际字符个数,否则返回第二个参数。」
  • prop->length 是之前预设的一个值,strnlen正常情况返回的就是字符串的长度 减1「去掉\n字符」。
  • *out_string = prop->value 这里就是二级指针起到作用了,没有重新分配内存,直接把指针指向字符串位置。

我们再看看prop 的结构体,就一目了然了。

struct property {
char *name;
int length;
void *value;
struct property *next;
unsigned long _flags;
unsigned int unique_id;
struct bin_attribute attr;
};
关于二级指针举个例子
#include "stdio.h"

char *str = "helloworld";
char **p = NULL;
int main(void)
{
p = &str;
printf("%s\n",*p);
return (0);
}
of_property_read_string 剖析~_嵌入式_02