设备树模型例子

设备树模型例子


嵌入式平台采用RK的,交叉编译工具链采用官方提供的交叉编译工具链。
1. 设备树文件

/ {
	fake_device {
		compatible = "fake_device";
		data = <0x20>;
		reg = <0x4a064000 0x800>;
		reg-names = "fake_reg";
		interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-names = "fake_interrput";
		string-property = "i am string";
		int-property = <0x33>;
		bool-property;
		fake_child {
			read_only;
			myname = "private";
			offset = <0>;
			size = <1024>;
		};
	};
};

2. 驱动文件

device_tree.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h> 
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>

static int my_pdrv_probe (struct platform_device *pdev)
{
	int data = 0;
	struct resource *res;
	int irq = 0;
	char my_string[64] = {0};
	const char *ps = my_string;
	int my_int = 0,size,offset;
	bool my_bool = false;
	struct device_node *np, *sub_np;
	/* registor */
	res = platform_get_resource_byname(pdev,IORESOURCE_MEM, "fake_reg");
	
	of_property_read_s32(pdev->dev.of_node, "data", &data);
	pr_info("data 0x%02x reg_name[%s] reg_start[%x] reg_end[%x]\n", data, res->name,res->start,res->end);
	/* interrput */
	irq = platform_get_irq_byname(pdev, "fake_interrput");
	pr_info("irq %d \n",irq);
	/* property */
	of_property_read_string(pdev->dev.of_node,"string-property", &ps);
	pr_info("string %s \n",my_string);
	of_property_read_s32(pdev->dev.of_node, "int-property", &my_int);
	pr_info("int 0x%02x \n",my_int);
	my_bool = of_property_read_bool(pdev->dev.of_node, "bool-property");
	if (my_bool)
	{
		pr_info("bool-property is true \n");
	}
	else
	{
		pr_info("bool-property is false \n");
	}
    
	/* sub_node */
	np = pdev->dev.of_node;
	for_each_child_of_node(np, sub_np)
	{
		of_property_read_s32(sub_np, "size", &size);
		of_property_read_s32(sub_np, "offset", &offset);
		pr_info("sub_node size = %d offset = %d\n",size,offset);
	}
    pr_info("module loaded\n");
    return 0;
}

static int my_pdrv_remove(struct platform_device *pdev)
{
    pr_info("module Unloaded\n");
    return 0;
}

static const struct of_device_id of_match_mypdrvs[] = {
	{ .compatible = "fake_device", .data = NULL },
	{ /* sentinel */ }
};

static struct platform_driver mypdrv = {
    .probe      = my_pdrv_probe,
    .remove     = my_pdrv_remove,
    .driver     = {
        .name     = "fake_device",
        .owner    = THIS_MODULE,
		.of_match_table = of_match_mypdrvs,
    },
};
module_platform_driver(mypdrv);
MODULE_AUTHOR("kingkim180");
MODULE_LICENSE("GPL");

3. Makefile

KERN_DIR = /opt/RV1126/kernel

all:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=$(shell pwd) modules 
clean:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=$(shell pwd) clean
	rm -rf modules.order ./*.ko ./*.o

obj-m	+= device_tree.o

4. 测试输出

root# insmod device_tree.ko
data 0x20 reg_name[fake_reg] reg_start[4a064000] reg_end[4a0647ff]
irq 75
string
int 0x33
bool-property is true
module loaded
sub_node size = 1024 offset = 0

加载驱动后内核自动识别到对应的compatible值后调用probe函数,输出对应的打印信息,这里的string没有识别到,查看源码发现这个内核不支持解析设备树字符串类型这个接口,没有输出,中断的值也有些问题,暂时没有看是什么导致的,hexdump /proc/device_tree/fake_device/interrupts查看值应该是对的,其他的值设置是正常的,通过设备树的方式就把用户自己设置的参数传递到驱动内部,从而同一厂商的多个芯片或者平台使用同一套的驱动程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值