zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.69k stars 6.53k forks source link

Assertion triggered when system is going to PM_STATE_SOFT_OFF #41944

Closed r2r0 closed 2 years ago

r2r0 commented 2 years ago

Describe the bug When I try to switch to SHUTDOWN mode using applicatiom PM policy then there is triggered system assertion from sched.c. The call stack reveals that there is scheduled semaphore waiting from the idle thread and it is not allowed. Platform: STM32WB55

Call stack: z_priq_rb_add -> __ASSERT_NO_MSG(!z_is_idle_thread_object(thread)) add_to_waitq_locked pend z_pend_curr z_impl_k_sem_take k_sem_take bt_hci_cmd_send_sync send_stack_reset shutdown_ble_stack pm_power_state_set pm_state_set pm_system_suspend idle

To Reproduce Steps to reproduce the behavior:

  1. Request system to switch to PM_STATE_SOFT_OFF on STM32WB55

Expected behavior No assertion should be triggered when system try to switch to PM_STATE_SOFT_OFF.

Impact showstopper

Logs and console output

Environment (please complete the following information):

Additional context

ceolin commented 2 years ago

yep, that is a real problem. The bluetooth stack takes a sempahore and we have an assert checking if it is the idle threa doing it. We don't want the idle thread being blocked ... also this operation can not be async since the soc will be powered down.

This particular situation seems ok to ignore the assert because is is happening when powering off the system ... if you build without asserts you everything should work fine ( I don't have this target to exercise it though).

The problem is real and I'll take some time investigating a proper solution for it.

r2r0 commented 2 years ago

@erwango Would it be possible to use asynchronous call (with polling) instead of bt_hci_cmd_send_sync?

erwango commented 2 years ago

@r2r0 I think that this would work indeed. Not need to add a supplemenary polling as it is already present with the following check in function shutdown_ble_stack.

while (LL_PWR_IsActiveFlag_C2DS() == 0) {

So the new code would looks like:

static void send_stack_reset(void)
{
    int err = 0;

    err = bt_hci_cmd_send(ACI_HAL_STACK_RESET, NULL);

    if (err) {
        LOG_ERR("M0 BLE stack reset issue");
    }
}
r2r0 commented 2 years ago

Thanks @erwango - PR submitted.