nRF5340, have interrupt make k_sleep() return early

I have an interrupt handler that sets a flag some of the time, and then runs other code in main whenever that flag is set. The code looks roughly like this:

bool my_flag = false;
void interrupt_handler()
{
    bool is_some_condition_true = false;
    /* ... */
    if (some_condition_true) {
        my_flag = true;
    }
}

int main()
{
    /* ... */
    
    while (true) {
        if (my_flag) {
            /* EXECUTE SOME CODE */
        }
        /* ... */
        k_sleep(K_MSEC(100);
    }
}

I have debugged my program such that if the goal is to run "EXECUTE SOME CODE" as quickly as possible, then the k_sleep() delay must be shortened. If it's too long, main() will continue sleeping for the remaining duration, then run another main loop iteration.

How can I adjust the code so that once I set the flag, I also stop sleeping and immediately start running the next main loop iteration?

I've already tried a couple things but they may not work due to other constraints and limitations. For example:

  • Simply reducing k_sleep() delay to smaller value has been proven to work, but it raises power consumption too much for our needs.
  • If I use something like sys_poweroff(), it becomes too aggressive; we have code that must run very regularly (every couple milliseconds) and the system takes too long to shut down and start back up in time to run the code.
  • Tried using k_wakeup() function (as AI answer suggested) but did not work.
  • Tried setting up simple semaphore (as AI answer suggested) but did not work.

Regardless, I would appreciate as many different suggestions as can be provided. Even if they may not immediately satisfy certain constraints, we'd still like to review it and check for ourselves. Right now we are just looking for any and all ideas that would work.

Parents
  • Those look all like anti patterns to me, i.e. patterns one should avoid.

    You can use semaphores to wake up a sleeping thread. Use k_sem_take() inside main function (or thread) instead of k_sleep. Interrupt allows you to call k_sem_give() in order to wakeup the sleeping thread very quickly.

    Alternatively you could look at the k_work stuff - I believe an interrupt can also call k_work_submit() or k_work_submit_to_queue() function from interrupt context. That would give you minimum delay even if there was other code running in main thread when the interrupt occurred.

Reply
  • Those look all like anti patterns to me, i.e. patterns one should avoid.

    You can use semaphores to wake up a sleeping thread. Use k_sem_take() inside main function (or thread) instead of k_sleep. Interrupt allows you to call k_sem_give() in order to wakeup the sleeping thread very quickly.

    Alternatively you could look at the k_work stuff - I believe an interrupt can also call k_work_submit() or k_work_submit_to_queue() function from interrupt context. That would give you minimum delay even if there was other code running in main thread when the interrupt occurred.

Children
No Data
Related