This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

device_get_binding keep returning null

Hello everyone,

I am working on an nRF52-DK and getting familiar with Zephyr.

In this process, I am trying to connect with the sensor API with a "fake" sensor whose driver just throws random values. So I am just exploring the possibilities.

On the main application, no matter what I do, I keep getting NULL when calling device_get_binding(DT_LABEL(MY_DEVICE));

Here is the main:

#define MY_DEVICE DT_PATH(soc, i2c_40003000, sens123_23)

#if !DT_NODE_HAS_STATUS(MY_DEVICE, okay)
#error "Node is disabled"
#endif

#if !DT_NODE_HAS_PROP(MY_DEVICE, reg)
#error "Device does not have reg properties"
#endif

const struct device *dev;

void main(void)
{
    /* Get the device */
	dev = device_get_binding(DT_LABEL(MY_DEVICE));
	if (dev == NULL) {
		/* No such node, or the node does not have status "okay". */
		printk("\nError: no device found.\n");
		return;
	}

    while(1)
    {
        k_sleep(K_MSEC(1000));
    }
}

Here is the "fake" sensor driver:

#define DT_DRV_COMPAT nec_sens123

struct sens123_data {
	const struct device *i2c;
	uint16_t a_sample;
	uint16_t b_sample;
};

static int sens123_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
    struct sens123_data *drv_data = dev->data;
	uint8_t buf[4] = {1, 2, 3, 4};

    __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

	drv_data->a_sample = (buf[0] << 8) + buf[1];
	drv_data->b_sample = (buf[2] << 8) + buf[3];

	return 0;
}

static int sens123_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	struct sens123_data *drv_data = dev->data;
	uint64_t tmp;

	/* val = -40 + 165 * sample / 2^16 */
	tmp = (uint64_t)drv_data->a_sample * 165U;
	val->val1 = (int32_t)(tmp >> 16) - 40;
	val->val2 = ((tmp & 0xFFFF) * 1000000U) >> 16;

	return 0;
}

static const struct sensor_driver_api sens123_driver_api = {
	.sample_fetch = &sens123_sample_fetch,
	.channel_get = &sens123_channel_get,
};

static int sens123_init(const struct device *dev)
{
	return 0;
}

static struct sens123_data sens123_data;

/*
DEVICE_DEFINE(DT_DRV_COMPAT, DT_INST_LABEL(0), sens123_init, NULL, &sens123_data,
	NULL,  POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
	&sens123_driver_api);
*/
DEVICE_DT_INST_DEFINE(0, &sens123_init, device_pm_control_nop,
		    &sens123_data, NULL, POST_KERNEL,
		    CONFIG_SENSOR_INIT_PRIORITY, &sens123_driver_api);

The device tree is based on the nRF52DK-nrf52832, and I added an overlay:

 

&i2c0{
    sens123@23 {
        compatible = "nec,sens123";
        label = "SENS123";
        reg = < 0x23 >;
    };
};

I put a basic .yaml binding in the zephyr/dts/binding/sensor folder, with the appropriate name. And here is the prj.conf:

CONFIG_LOG=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_SENS123=y

In the app folder, I have a folder called drivers. Then a folder called sens123 with the sens123.c inside. At all levels, I put the appropriate Kconfig and CMakeLists.txt.*

I am certainly missing something very basic but, for the life of me, I can't figure out what.

I would be very grateful for any help you can bring me. Feel free to ask me about any additionnal information you may need.

Best regards,

Related