Hello,
I'm working on a project using the nRF52840 and Zephyr, and I'm experiencing an issue when trying to use device power management (PM) with a custom sensor driver.
Environment:
-
nRF Connect SDK v2.5.2
-
Toolchains v2.7.0
-
IDE: nRF Connect for VS Code extension
I am attaching a minimal project that reproduces the problem to facilitate support.
Device Definition
I am defining the device as follows in my driver:
#define KX132_SPI(inst) \
(.spi = SPI_DT_SPEC_INST_GET(inst, SPI_OP_MODE_MASTER | \
SPI_MODE_CPOL | SPI_TRANSFER_MSB | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), )
#define KX132_DEFINE(inst) \
static struct kx132_data kx132_data_##inst; \
static const struct kx132_device_config kx132_device_config_##inst = { \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), KX132_SPI(inst), ()) \
}; \
PM_DEVICE_DT_INST_DEFINE(inst, kx132_pm_action); \
SENSOR_DEVICE_DT_INST_DEFINE(inst, kx132_init, PM_DEVICE_DT_INST_GET(inst), \
&kx132_data_##inst, &kx132_device_config_##inst, APPLICATION, \
CONFIG_SENSOR_INIT_PRIORITY, &kx132_driver_api);
This should correctly register the device with a power management callback (kx132_pm_action).
I'm also logging the following config macros at runtime to ensure they are enabled:
#ifdef CONFIG_PM_DEVICE
LOG_INF("CONFIG_PM_DEVICE");
#endif
#ifdef CONFIG_PM
LOG_INF("CONFIG_PM");
#endif
#ifdef CONFIG_PM_DEVICE_RUNTIME
LOG_INF("CONFIG_PM_DEVICE_RUNTIME");
#endif
All of these are active in my configuration and appear in the log during startup.
The Issue
When I attempt to turn off the device using the following code:
if (!device_is_ready(sensor)) {
LOG_ERR("Sensor device not ready");
return -ENODEV;
}
LOG_INF("Pointer do sensor: %p, nome: %s", sensor, sensor->name);
enum pm_device_state state;
int st_ret = pm_device_state_get(sensor, &state);
LOG_INF("Estado atual do sensor: %d, ret: %d", state, st_ret);
LOG_INF("Chamando PM_DEVICE_ACTION_TURN_OFF para o sensor");
int ret = pm_device_action_run(sensor, PM_DEVICE_ACTION_TURN_OFF);
LOG_INF("Resultado do PM_DEVICE_ACTION_TURN_OFF: %d", ret);
return ret;
I get the following log output:
<inf> ACCEL: Pointer do sensor: 0x35a44, nome: kx132@1 <inf> ACCEL: Estado atual do sensor: 0, ret: 0 <inf> ACCEL: Chamando PM_DEVICE_ACTION_TURN_OFF para o sensor <inf> ACCEL: Resultado do PM_DEVICE_ACTION_TURN_OFF: -134
-
The pointer and device name match as expected.
-
The state of the device is ACTIVE (0).
-
However, calling
pm_device_action_run()always returns -134 (-ENOTSUP). -
The callback function
kx132_pm_action()is never called (no log inside it appears).
What I Expect
-
I expect the PM callback (
kx132_pm_action) to be called when I runpm_device_action_run(), but this does not happen. -
All PM macros are enabled, the device is properly registered, and the device pointer is correct.
-
If I register the device using
DEVICE_DT_INST_DEFINEinstead ofSENSOR_DEVICE_DT_INST_DEFINE, the PM callback is called as expected.
Suspected Problem
It seems that SENSOR_DEVICE_DT_INST_DEFINE (and possibly SENSOR_DEVICE_DT_DEFINE) is not properly associating the PM structure with the device, or Zephyr is not enabling PM for this sensor device, despite all settings appearing to be correct.
Steps to Reproduce
-
Use the macros shown above in a sensor driver.
-
Build with
CONFIG_PM,CONFIG_PM_DEVICE, andCONFIG_PM_DEVICE_RUNTIMEenabled. -
Call
pm_device_action_run()for the sensor device. -
Observe that the PM callback is not called and the return is always
-ENOTSUP.
Could you clarify if this is a bug, a missing configuration, or if there are additional requirements for enabling PM for sensors defined with SENSOR_DEVICE_DT_INST_DEFINE?
I'm attaching the minimal project that reproduces the issue.
Thanks in advance!