概述
目录
一、标准属性
二、根节点下的compatible属性
三、Linux内核的OF操作函数
四、OF函数实验
一、标准属性
1、compatible属性(兼容的)
值是字符串列表,用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序
2、model属性
属性值也是一个字符串,一般model属性描述模块信息,比如名字之类
3、status属性
属性值也是一个字符串,用来描述一个设备的状态
4、#address-cells和#size-cells属性
两个属性值都是无符号32位整型,#address-cells和#size-cells可以用在任何拥有节点的设备中,用于描述节点的地址信息,#address-cells决定了子节点reg属性中地址信息所占用的字长(32位),#size-cells属性值决定了子节点reg属性中长度信息所占用的字长
#address-cells = <1>;
#size-cells = <1>;
子节点: reg = <cell1 cell2>
reg = <0x02198000 0x4000>
5、ranges属性
代表地址映射,如果是null则表示没有地址映射
6、device_type属性
用来描述设备的Fcode //CPU、memory节点
二、根节点下的compatible属性
内核启动的时候会检查是否支持此平台
不使用设备树时,通过传递machine id 来判断内核是否支持此平台
使用设备树时,不使用机器ID,而是使用根节点下的compatible属性
三、Linux内核的OF操作函数
1、驱动如何获取到节点信息。在驱动中使用OF函数获取设备树属性内容。
2、驱动要想获取到设备树内容,首先要找到节点
①、of_find_node_by_name
②、of_find_node_by_type
③、of_find_node_by_path
④、of_find_compatible_node
3、提取属性值的OF函数
节点的属性信息里面保存了驱动所需要的内容,因此对于属性值的提取非常重要, Linux 内核中使用结构体 property 表示属性
struct property {
char *name; /* 属性名字 */
int length; /* 属性长度 */
void *value; /* 属性值 */
struct property *next; /* 下一个属性 */
unsigned long _flags;
unsigned int unique_id;
struct bin_attribute attr;
};
①、of_find_property函数
用于查找指定的属性
②、of_property_count_elems_of_size 函数
用于获取属性中元素的数量
③、of_property_read_u32_index 函数
从属性中获取指定标号的 u32 类型数据值(无符号 32位),比如某个属性有多个 u32 类型的值,那么就可以使用此函数来获取指定标号的数据值
④、of_property_read_u8_array 函数
of_property_read_u16_array 函数
of_property_read_u32_array 函数
of_property_read_u64_array 函数
这 4 个函数分别是读取属性中 u8、 u16、 u32 和 u64 类型的数组数据,比如大多数的 reg 属性都是数组数据,可以使用这 4 个函数一次读取出 reg 属性中的所有数据
⑤、of_property_read_u8 函数
of_property_read_u16 函数
of_property_read_u32 函数
of_property_read_u64 函数
有些属性只有一个整形值,这四个函数就是用于读取这种只有一个整形值的属性,分别用于读取 u8、 u16、 u32 和 u64 类型属性值
⑥、of_property_read_string 函数
用于读取属性中字符串值
⑦、of_n_addr_cells 函数
函数用于获取#address-cells 属性值
⑧、of_n_size_cells 函数
函数用于获取#size-cells 属性值
四、OF函数实验
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
static int __init dtsof_init(void)
{
int ret = 0;
struct device_node *bl_nd = NULL;
struct property *comppro = NULL;
const char *str;
u32 def_val = 0;
u32 elemsize = 0;
u32 *brival;
int i;
/* 1. find backlight node */
bl_nd = of_find_node_by_path("/backlight");
if(bl_nd == NULL) { /*failed*/
ret = -EINVAL;
goto fail_finded;
}
comppro = of_find_property(bl_nd, "compatible", NULL);
if(comppro == NULL) {
ret = -EINVAL;
goto fail_finpro;
} else {
printk("compatible=%sn", (char *)comppro->value);
}
/* 2. read string */
ret = of_property_read_string(bl_nd, "status", &str);
if(ret < 0) {
goto fail_rs;
} else {
printk("status=%srn", str);
}
/* 3. read number */
ret = of_property_read_u32(bl_nd, "default-brightness-level", &def_val);
if(ret < 0) {
goto fail_read32;
} else {
printk("default-brightness-level=%drn", def_val);
}
/* 4. read arr[] */
elemsize = of_property_count_elems_of_size(bl_nd, "brightness-levels", sizeof(u32));
if(elemsize < 0) {
ret = -EINVAL;
goto fail_readele;
} else {
printk("brightness-levels=%drn", elemsize);
}
/* 5. kmalloc */
brival = kmalloc(elemsize * sizeof(u32), GFP_KERNEL);
if(!brival) {
ret = EINVAL;
goto fail_mem;
}
ret = of_property_read_u32_array(bl_nd, "brightness-levels", brival, elemsize);
if(ret < 0) {
goto fail_read32array;
} else {
for(i = 0; i < elemsize; i++)
printk("brightness-levels[%d] = %drn", i, *(brival + i));
}
kfree(brival);
return 0;
fail_read32array:
kfree(brival);
fail_mem:
fail_readele:
fail_read32:
fail_rs:
fail_finpro:
fail_finded:
return ret;
}
static void __exit dtsof_exit(void)
{
printk("dtsof_exitn");
}
module_init(dtsof_init);
module_exit(dtsof_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ZHANG");
最后
以上就是勤劳航空为你收集整理的Linux驱动编程【OF函数操作】的全部内容,希望文章能够帮你解决Linux驱动编程【OF函数操作】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复