Skip to content
Snippets Groups Projects

Dispatch interrupts asynchroneously

Merged rahix requested to merge rahix/interrupts into master

This patch-set changes interrupt dispatching to happen asynchronously. This is a first step towards making API-calls interrupt safe. It also makes Epicardium more robust against a buggy payload as such a payload can no longer deadlock tasks which try to send interrupts (in such an instance, now they will be scheduled but never leave the IRQ queue).

Patch-List:

chore(interrupts): Make api_interrupt_trigger() return void

api_interrupt_trigger() cannot fail except by a programmer error (passing an invalid ID) in which case we should raise an assertion. Thus, make it return void instead of int.

fix(lifecycle): Don't trigger a reset during startup

This is a silent issue which I noticed during work in this patchset; we are sending a superfluous interrupt during boot. This patch changes this although it reduces readability of the code. I'd be ok with dropping it again if readability here is more important.

chore(interrupts): Move api into an epicardium module

Our buildsystem prevents implementing the task in epicardium/api so I moved the interrupts API into an Epicardium module.

chore(interrupts): Fix all modules to use new api

Update code-base to use new API.

feat(interrupts): Dispatch interrupts asynchroneously

Instead of blocking the triggering task when core 1 is still busy handling the previous interrupt, offload interrupt dispatching into a separate task. This is the first step towards making API-calls interrupt safe.

Next to the async triggering, the synchroneous mechanism is retained for special cases where async does not work (e.g. because of spin-locks). Currently, there is only one such case when resetting core 1 (triggering EPIC_INT_RESET).

docs(interrupts): Document new interrupt dispatcher task

Docs ...

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • schneider
  • schneider
  • schneider
  • schneider
  • I thought about all the sensor stream related things

  • Author Owner

    They actually don't use the interrupts at all IIRC. They just poll the sensor-stream continuously ...

  • The SpO2 app which uses interrupts is still working.

    I'd ask for some more documentation. Then this is ready.

  • rahix added 26 commits

    added 26 commits

    • d834d48c...861d604a - 20 commits from branch master
    • 079b9344 - chore(interrupts): Make api_interrupt_trigger() return void
    • 8bb6a743 - fix(lifecycle): Don't trigger a reset during startup
    • fc57e82f - chore(interrupts): Move api into an epicardium module
    • 5abd0cd0 - chore(interrupts): Fix all modules to use new api
    • f8d75535 - feat(interrupts): Dispatch interrupts asynchroneously
    • f5dbaac0 - docs(interrupts): Document new interrupt dispatcher task

    Compare with previous version

    • Author Owner
      Resolved by schneider

      I just noticed something ... :(

      This code snippet

      import interrupt
      import utime
      
      def handler(_):
          print("handling IRQ")
      
      
      interrupt.set_callback(interrupt.RTC_ALARM, handler)
      interrupt.enable_callback(interrupt.RTC_ALARM)
      
      utime.alarm(utime.time() + 2)
      
      while True:
          print("And going to sleep ...")
          utime.sleep(5)

      triggers a panic. Seems like I didn't test all code-paths through the RTC module and missed something important:

      The current implementation of the RTC driver calls interrupt_trigger() from the RTC IRQ. This fails horribly because interrupt_trigger() wants to do multiple things which can't ever happen from an interrupt (locking a mutex, calling xTaskNotifyGive()).


      The proper solution to this would be refactoring the RTC module to have no logic in the IRQ handler and instead have a task woken up which actually dispatches the interrupt.

      But this is also not great; yet another task which sits idle 99% of the time wasting RAM in epicardium. The number of these has gotten considerably large already ... So the proper proper solution would be finally implementing a worker-queue which takes all those work items that currently have their own tasks and runs them. But I'm not up to implementing such a thing right now ...

      So, I would suggest the following: I build an 'unsafe' (that is, not checking the lock for interrupt_data.int_enabled) version of interrupt_trigger_sync() which can be called from an IRQ and which is only used in this one place. And we hopefully fix the RTC module properly soon(tm) ...

  • rahix added 21 commits

    added 21 commits

    • f5dbaac0...12992926 - 15 commits from branch master
    • 0b845e99 - chore(interrupts): Make api_interrupt_trigger() return void
    • 079982a6 - fix(lifecycle): Don't trigger a reset during startup
    • 1f7e44e6 - chore(interrupts): Move api into an epicardium module
    • 682565f2 - chore(interrupts): Fix all modules to use new api
    • 37e7fb35 - feat(interrupts): Dispatch interrupts asynchroneously
    • 3d4d0eb4 - docs(interrupts): Document new interrupt dispatcher task

    Compare with previous version

  • Looks good to me! Thanks for keeping our codebase clean.

    However, I'm only a bot - so a human will still have to approve this request.

  • rahix added 4 commits

    added 4 commits

    • 52b1fbbc - chore(interrupts): Move api into an epicardium module
    • 7b56f29a - chore(interrupts): Fix all modules to use new api
    • 79a0d3d5 - feat(interrupts): Dispatch interrupts asynchroneously
    • 5209505d - docs(interrupts): Document new interrupt dispatcher task

    Compare with previous version

  • rahix added 1 commit

    added 1 commit

    • 4b171bea - docs(interrupts): Document changed interrupt behavior

    Compare with previous version

  • Author Owner

    @schneider, I tried addressing all remaining comments. Can you take another look?

  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Please register or sign in to reply
    Loading