无法在Zephyr中获得设备绑定



我想使用设备名称获得设备绑定,但由于某种原因,当我只使用节点id时,它失败了。当我使用"full">

我的代码

#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#define I2C_DEV_NAME "i2c@3ff53000" // works
//#define I2C_DEV_NAME "i2c0" // does not work, dev is null
void check_i2c(void)
{
const struct device* const dev = device_get_binding(I2C_DEV_NAME);
if (!dev) {
printk("Failed to get device %sn", I2C_DEV_NAME);
return;
}
printk("i2c device is ready to usen");
}
void main(void)
{
check_i2c();
while (1) {
k_sleep(K_SECONDS(1));
}
}

*。dtsi文件:

i2c0: i2c@3ff53000 {
compatible = "espressif,esp32-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x3ff53000 0x1000>;
interrupts = <I2C_EXT0_INTR_SOURCE>;
interrupt-parent = <&intc>;
clocks = <&rtc ESP32_I2C0_MODULE>;
status = "disabled";
};

* .dts

&i2c0 {
status = "okay";
clock-frequency = <I2C_BITRATE_STANDARD>;
sda-gpios = <&gpio0 21 GPIO_OPEN_DRAIN>;
scl-gpios = <&gpio0 22 GPIO_OPEN_DRAIN>;
pinctrl-0 = <&i2c0_default>;
pinctrl-names = "default";
};

id为'i2c0'的节点已经存在,并且已经启用,为什么它不能工作?

我用的是esp32板。

如注释所述,一般来说,i2c0等节点标签在编译时不会最终成为最终devicetree的一部分;并且它不用作device_get_binding()使用的设备名(它也不同于devicetree宏中使用的节点id)。但是需要注意的是,Zephyr在编译时使用devicetree,并且通常通过宏访问它,而不是像Linux那样在运行时访问它——因此,在构建系统处理devicetree时,Zephyr可以访问比Linux更多的东西。

当涉及到设备和Zephyr中的设备树时,可能会更清楚地区分不同的概念:

device——一个由驱动程序提供的结构指针,在所有API调用中使用,所以这就是我们想要得到的

设备名称-用于在运行时识别设备的字符串,它是给device_get_binding()的,并且是标签属性或节点的全名

node full name -在devicetree中以字符串形式显示节点名和单元地址;这是name@address字符串,将用作设备名称(如上面的i2c@3ff53000)

node label——在devicetree中,节点标签被赋予一个节点,以便更容易地引用节点;这是你的i2c0。一个典型的复杂性是一个节点可以有许多标签,但通常设备树中的一个节点只有一个。

label属性—如果devicetree节点的属性为label,则该值将代替Zephyr中节点的设备名称的全名(如label = "DEV";;你没有这个,但我想提一下,这样你就知道了)

节点id——这通常是Zephyr用来在devicetree宏中引用设备树中的节点的,它充当节点的句柄,以便您可以访问它并在树中导航。它不是树本身的东西,只是构建系统引用节点的方式。

有了这些,有两种方法来处理你的情况。如前所述,节点标签不用作设备名称,但我们可以使用devicetree宏从标签中获取名称:
// First get the node id from the node label, then get the name from the node id
#define I2C_DEV_NAME DEVICE_DT_NAME(DT_NODELABEL(i2c0))
...
dev = device_get_binding(I2C_DEV_NAME);

然而,在运行时使用设备名字符串获取设备结构指针并不是最有效的方法,因为你在编译时已经知道了所有的东西(这种方法可以追溯到Zephyr;并且必须循环遍历设备数组对每个设备名称和请求的名称进行字符串比较)。多亏了devicetree宏,我们应该能够直接从节点id中获得设备结构指针,而我们可以从标签中获得,所有这些都在编译时完成:

dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
// Shouldn't need to null pointer check as the above will fail in compilation if i2c0 doesn't exist

还有更多的选项,如别名,但希望这有助于尝试了解Zephyr在做什么,以及如何使设备更容易。

相关内容

  • 没有找到相关文章

最新更新