我正在为看门狗编写一个 Linux 内核驱动程序,使用 CPU 的内部寄存器和(持久)RAM 中的一个专用位置,用于在看门狗触发重置的情况下存储调试信息。
在旧世界,我有两个类型为 IORESOURCE_MEM
的资源在我的电路板文件中:内部寄存器(内部寄存器的基地址加上偏移量)和 RAM 中的位置(绝对内存地址)。
我可以通过 platform_get_resource()
访问这些使用适当的索引,然后我可以重新映射。
在具有设备树的新世界中,我的看门狗节点位于内部 CPU 寄存器域中,我可以毫无问题地访问它们。
但是如何在 RAM 中添加我的内存位置? RAM 的基地址与 CPU 内部寄存器不同,所以我不能只向“reg”条目添加另一个范围(如 reg = <0x20300 0x408>, <0x3BFFE000 0x1000>;
)。也许我需要添加这样的新“设备”吗?
PRAM {
#address-cells = <1>;
#size-cells = <1>;
PRAM0: Watchdog_Crash_Debug_Context {
reg = <0x3BFFE000 0x1000>;
};
};
但是我如何在看门狗设备驱动程序中引用它呢?或者在看门狗设备树条目中?
Linux 版本为 4.1.18。
最佳答案
与此同时,我自己找到了解决方案。 secret 是魔法函数 of_parse_phandle()
。
设备树设置:
soc {
...
internal-regs {
...
watchdog_global {
...
PRAM_address = <&PRAM0>;
};
};
};
PRAM {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0x3b000000 0x5000000>;
PRAM0: Watchdog_Crash_Debug_Context {
reg = <0xFFE000 0x1000>;
};
};
代码中的用法(真的很简单!):
struct device_node *PRAM_node = of_parse_phandle(pdev->dev.of_node, "PRAM_address", 0);
debug_info = of_iomap(PRAM_node, 0);
of_node_put(PRAM_node);
其中pdev->dev.of_node
是指设备树节点watchdog_global
,debug_info
是指向自定义结构体的指针。
关于c - 如何使用设备树在一个 Linux 内核驱动程序中映射两个设备的资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37007911/