/* 在dts文件下增加这几行 */
/{
test1:test_device_tree{
compatible = "test_compatible";
gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
};
}
struct device_node *np = pdev->dev.of_node; //设备树中
struct resource *led_resource; //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;
}
}
//设备树
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
//设备树
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
/* 作用 : 查找设备树中特定节点的函数
* 传入参数 :
* 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");
/* 作用 : 根据节点的路径查找节点
* 传入参数 :
* path : 一个以斜杠(/)分隔的字符串,表示设备树中从根节点到目标节点的路径
* 返回值 : 如果找到了匹配名称的节点,函数将返回该节点的指针(struct device_node*)。否则返回NULL。
*/
of_find_node_by_path(const char *path);
/*------- 示例 --------*/
/* "/topeet/myled" : 在根节点下的topeet节点中,找到myled节点
*/
of_find_node_by_path("/topeet/myled");
/* 作用 : 获取指定节点的父节点
* 传入参数 :
* 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
/* 作用 : 获取指定节点的父节点
* 传入参数 :
* 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
/* 作用 : 通过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");
/* 作用 : 查找节点下指定的属性
* 传入参数 :
* 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);
/* 作用 : 获取属性中元素的数量
* 传入参数 :
* 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
/* 作用 : 获取属性中元素的数量
* 传入参数 :
* 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);
/* 作用 : 获取属性中元素的数量
* 传入参数 :
* 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
/* 作用 : 读取属性中的字符串
* 传入参数 :
* 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