设备树OF函数操作实验-读取设备节点的整型数组元素的属性

发布时间:2024年01月14日

一.? 简介

本文学习使用设备树操作 OF函数,读取设备节点的整型的属性值。

读取设备树文件 imx6ull-14x14-evk.dts 中一个设备节点的信息。这里读取 backlight设备节点的 brightness-levels属性值。

二. 读取设备节点的整型数组元素的属性

?1.? backlight设备节点信息

imx6ull-14x14-evk.dts文件中 backlight设备节点信息如下:

backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm1 0 5000000>;
		brightness-levels = <0 4 8 16 32 64 128 255>;
		default-brightness-level = <6>;
		status = "okay";
	};

这里准备读取 imx6ull-14x14-evk.dts 设备树文件中 default-brightness-level属性的值。

主要使用如下的设备树 OF操作函数 :

struct device_node *of_find_node_by_path(const char *path);  //获取设备节点
int of_property_count_u32_elems(const struct device_node *np,
const char *propname);  //读取数组元素的个数
static inline int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz);  //读取数组元素

这里还动态申请了空间,使用了 kmalloc()函数与释放内存函数 kfree()函数。函数原型如下:

void *kmalloc(size_t size, int flags);
void kfree(void *ptr);

kmallc()函数的参数 flags:常用的标志是GFP_KERNEL,表示内存分配是代表运行在内核空间的进程执行的。

2.? 代码实现

下面开始读取数组中所有元素的值,代码实现如下:

#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>

/*模块入口*/
static int __init dtsof_init(void)
{
    int ret = 0;
    struct device_node * dev_node = NULL;
    int element_numbers = 0;
    u32* element_ptr = NULL;
    int  i = 0;

    //1. 读取设备节点
    dev_node = of_find_node_by_path("/backlight");
	if(NULL == dev_node)
    {
        ret = -EINVAL;
        goto find_dev_node_failed;
    }

    //2. 读取数组元素的个数
    element_numbers = of_property_count_u32_elems(dev_node, "brightness-levels");
	if(element_numbers < 0)
    {
        ret = -EINVAL;
        goto get_element_number_failed;
    }	
    printk("element_number: %d\r\n", element_numbers);	

    //3. 动态申请内存
    element_ptr = kmalloc(element_numbers * sizeof(u32), GFP_KERNEL);
    if(!element_ptr)
    {
        ret = -EINVAL;
        goto kmalloc_failed;
    }

    //4. 获取整型数组的元素值
    ret =  of_property_read_u32_array(dev_node, "brightness-levels", element_ptr, element_numbers);
	if(ret != 0)
    {
        ret = -EINVAL;
        goto get_u32_array_failed;
    }	

    for(i = 0; i < element_numbers; i++)
    {
        printk("brightness-levels[%d]: %d\r\n", i, element_ptr[i]);
    }	

    kfree(element_ptr);   

kmalloc_failed:
get_u32_array_failed:
get_element_number_failed:
find_dev_node_failed:
    return ret;
}

/*模块出口*/
static void __exit dtsof_exit(void)
{

}

/*模块入口与出口*/
module_init(dtsof_init); 
module_exit(dtsof_exit);

/*模块 Licence*/
MODULE_LICENSE("GPL");
/*模块作者*/
MODULE_AUTHOR("LingXueWu");

三.? 编译驱动与加载驱动

???1.? 编译程序

ubuntu 终端进入 4_dtsof工程根目录下编译工程:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/4_dtsof$ make

编译后,生成驱动文件 dtsof.ko。

将 dtsof.ko拷贝到开发板系统下 /lib/modules/4.1.15/目录下:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/4_dtsof$ sudo cp dtsof.ko /home/wangtian/linux/nfs_File/rootfs/lib/modules/4.1.15/ -f

2.? 加载驱动

这里不需要先运行 depmod命令。因为前面已经运行过一次。

开发板上电进入系统 /lib/modules/4.1.15/目录下,加载 dtsof.ko 驱动模块:

/ # cd /lib/modules/4.1.15/
/lib/modules/4.1.15 # modprobe dtsof.ko 
element_number: 8
brightness-levels[0]: 0
brightness-levels[1]: 4
brightness-levels[2]: 8
brightness-levels[3]: 16
brightness-levels[4]: 32
brightness-levels[5]: 64
brightness-levels[6]: 128
brightness-levels[7]: 255
/lib/modules/4.1.15 # 

?测试结束后,卸载驱动模块,输入如下命令:

/lib/modules/4.1.15 # rmmod dtsof.ko 

文章来源:https://blog.csdn.net/wojiaxiaohuang2014/article/details/135578247
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。