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_DEFINE
instead 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_RUNTIME
enabled. -
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!
pm_device.zip