Subscribing to power manager events.

Hi!

I am trying to subscribe to the power management events that correspond to the following log lines (which I can clearly see in the log):

I: POWER event ready
I: POWER event removed
I: SUSPEND state detected
I: RESUMING from suspend

I have been trying with this code:

#include "power.h"
#include <zephyr/logging/log.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/state.h>
#include <zephyr/pm/pm.h>

LOG_MODULE_REGISTER(my_module, LOG_LEVEL_INF);

void pm_notifier_cb(enum pm_state state)
{
    printk("PM: %i", state);
}

static struct pm_notifier notifier = {
    .state_entry = pm_notifier_cb,
    .state_exit = pm_notifier_cb,
};

void InitPower(void) {
    printk("Power Init");
    pm_notifier_register(&notifier);
}

I have extended prj.conf with:

CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_PM_DEVICE=y
CONFIG_PM=y


Results:

  • - "Power Init" is getting printed just fine
  • - but the callback is never called.

Setup:

  • - NCS_VERSION=v2.6.0
  • - Running from Ubuntu
  • - Any other info needed?

Any idea what I am doing wrong?

Parents
  • Hello,

    Support for the PM subsystem (CONFIG_PM, not CONFIG_PM_DEVICE) was removed in SDK v2.5.0 by this commit: https://github.com/nrfconnect/sdk-zephyr/commit/96b38273138f05dd06cf7a58fa361f401e773e5e. So, unless you have reverted this change, you should be getting a Kconfig warning in your build output stating that the CONFIG_PM symbol did not end up being selected. 

    Does this application allow the idle thread to be run?

    Best regards,

    Vidar

  • Well, as for warnings, I am getting this, but to tell the truth I find it rather unintelligible and the "see ..." section is not very helpful:

    warning: PM (defined at soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.series:18,
    soc/arm/silabs_exx32/efr32bg27/Kconfig.defconfig.series:18,
    soc/arm/silabs_exx32/efr32mg24/Kconfig.defconfig.series:19,
    soc/arm/st_stm32/stm32f4/Kconfig.defconfig.series:20, subsys/pm/Kconfig:13) was assigned the value
    'y' but got the value 'n'. Check these unsatisfied dependencies: ((SOC_SERIES_EFR32BG22 &&
    SOC_FAMILY_EXX32) || (SOC_SERIES_EFR32BG27 && SOC_FAMILY_EXX32) || (SOC_SERIES_EFR32MG24 &&
    SOC_FAMILY_EXX32) || SOC_SERIES_STM32F4X || (SYS_CLOCK_EXISTS && HAS_PM)) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_PM and/or look up PM in the
    menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values,
    and Kconfig - Tips and Best Practices sections of the manual might be helpful too.

    The relevant excerpt from `kernel threads` and thread analyzer logs (after adding some `CONFIG_THREAD_ANALYZER` options) is:
    $kernel threads 
    
    ...
    
     0x2000cfc0 idle
            options: 0x1, priority: 15 timeout: 0
            state: , entry: 0x5e245
            Total execution cycles: 999756 (72 %)
            stack size 320, unused 272, usage 48 / 320 (15 %)
    
     0x2000d098 main
            options: 0x1, priority: 0 timeout: 17
            state: suspended, entry: 0x5d731
            Total execution cycles: 193498 (14 %)
            stack size 2048, unused 1128, usage 920 / 2048 (44 %)
    
    ...
    
    Thread analyze:
     idle                : STACK: unused 272 usage 48 / 320 (15 %); CPU: 73 %
          : Total CPU cycles used: 1442089
     main                : STACK: unused 1128 usage 920 / 2048 (44 %); CPU: 13 %
          : Total CPU cycles used: 271937
     ISR0                : STACK: unused 904 usage 1144 / 2048 (55 %)

    Based on this I would say that yes it is allowed to run.

    (I have removed other threads since they are a potentially sensitive information.)

  • I see.

    Our project uses c2usb to handle USB, that in turn uses zephyr's udc. As a result, using usb_enable directly is not possible (it results in multiple registrations for irq 39). I guess I shall delegate this on our usb expert.

    If you have any further comments, they are welcome, otherwise I consider this solved.

    Thanks for help!

  • (I assume you mean when some version that compiles is released.)

    Thanks!

  • (I assume you mean when some version that compiles is released.)

    Sorry, I'm not sure I follow. Are you talking about an internal release on your end?

  • Well, sorry, I am confused, especially as to the anatomy of the zephyr ecosystem and its .release cycle

    Where exactly am I supposed to obtain `usbd_msg_register_cb`?

    Clearly, usbd_msg_register_cb is defined in the `sdk-zephyr` repository master branch, however is not part of the sdk-zephyr repository that I have installed via nrfutil. It seems to be part of some *future* release. I am not sure if it is possible for me to get development version - I have certainly not found instructions on how to anywhere. Just checking out main branch in the repository leads to a large number of kconfig errors...

    Part of what I am confused about is that zephyr sdk is said to not be part of nrf connect sdk, and has listed separate installation instructions. Yet sdk-zephyr is installed during the nrf connect sdk toolchain installation process. Is sdk-zephyr not zephyr sdk? The fact that installation guide points to github.com/.../sdk-ng rather than https://github.com/nrfconnect/sdk-zephyr suggests that too.

Reply
  • Well, sorry, I am confused, especially as to the anatomy of the zephyr ecosystem and its .release cycle

    Where exactly am I supposed to obtain `usbd_msg_register_cb`?

    Clearly, usbd_msg_register_cb is defined in the `sdk-zephyr` repository master branch, however is not part of the sdk-zephyr repository that I have installed via nrfutil. It seems to be part of some *future* release. I am not sure if it is possible for me to get development version - I have certainly not found instructions on how to anywhere. Just checking out main branch in the repository leads to a large number of kconfig errors...

    Part of what I am confused about is that zephyr sdk is said to not be part of nrf connect sdk, and has listed separate installation instructions. Yet sdk-zephyr is installed during the nrf connect sdk toolchain installation process. Is sdk-zephyr not zephyr sdk? The fact that installation guide points to github.com/.../sdk-ng rather than https://github.com/nrfconnect/sdk-zephyr suggests that too.

Children
  • My bad. I didn't realize that the said function is not available in the current release as I was looking at the latest documentation. Also, I confused the USB device stack API with the USB device controller driver APIs. As far as I can tell, the c2usb library is only using the latter. Either way, I have not found anyone who are familiar with the c2usb library internally, so I'm not sure if there is any easy way to get it to propagate USB state events to the application. 

    The nRF Connect SDK includes this fork of Zephyr: https://github.com/nrfconnect/sdk-zephyr 

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.6.1/nrf/dev_model_and_contributions/code_base.html#dm-code-base 

  • Acually, we collaborate with c2usb's creator, so as to its modifications, we should be fairly flexible. (I just didn't realize at first that this is a usb driver/stack issue.) (In this respect, feel free to give just a few pointers and tell me to delegate it to him...)

    In the meanwhile, I have tested Benedek's amend of c2usb, which forwards on some kind of power-related usb events. Maybe the code below tells you more (if not, no worries). Unfortunatelly, it often reports states that are irrelevant to the actual power state.

        usb_manager()
        {
            device_.set_power_event_delegate([](usb::df::device &dev, usb::df::device::event ev) {
                using event = enum usb::df::device::event;
                switch (ev) {
                case event::CONFIGURATION_CHANGE:
                    printk("USB configured: %u, granted current: %uuA\n", dev.configured(), dev.granted_bus_current_uA()); 
                    break;
                case event::POWER_STATE_CHANGE:
                    printk("USB power state: L%u, granted current: %uuA\n", 3 - static_cast<uint8_t>(dev.power_state()), dev.granted_bus_current_uA());
                    break;
                }
            });
        }

    Which further points to github.com/.../device.hpp

    Unlike above benedek's code, the POWER events in the log seem fairly reliable, except...

    When the board is restarted, we get no callback from Benedek's code, neither the POWER event ready event shows up in the log.

    So what we need is to also figure a way to explicitly inquire for the power state...

Related