Interrupt-driven architecture
The current architecture of the firmware is a polling super loop. This may be the simplest architecture to implement and reason about, but it is not efficient or reliable.
An event-driven system allows us to:
- Handle events when they happen, not whenever we get to them
- Reduce CPU overhead: No longer checking conditions that may be false most of the time
- Put the EC in Idle mode for additional power savings (#199)
Drawbacks
- Entire codebase must be evaluated for things such as:
- Blocking IO
- Non-reentrant functions
- Critical sections and atomic access
- Variable to be accessed in ISRs not marked
volatile
- Possibility of an interrupt storm degrading usability
- Difficultly of reproducing/debugging problems
Details
The EC has the concept of "internal" and "external" events that trigger interrupts. All* are routed through the 8051 INT1# line. (*IT8587E does use INT0 for a couple things.)
- Internal (INTC): Triggered by EC modules
- External (WUC): Triggered by GPIOs from the board
A potential path for implementing interrupt handling is:
- Move
INT1#ISR from common code to EC code - Acknowledge any interrupt the occurs to prevent a storm
- IT5570E has a single non-maskable interrupt: INT159
- Enable EX1
INTC can now receive interrupts. All source are masked by default, so only the NMI will assert INT1# and call the ISR.
- Implement INTC logic
- Should be common between both ITE ECs
Logic for enabling, disabling, configuring, and acknowledging INTC interrupts may be common between ECs. The IRQs are specific to each EC.
WUC sources are per-board: GPIOs correspond to different functionality. E.g., LAN_WAKEUP# is not available on lemp9/lemp10, GPH4 on darp7, and GPB2 on the rest of the boards.
- Implement mechanism for configuring external interrupts
- Should be common between both ITE ECs
- Must be able to associate a GPIO with:
- WUC group and bit offset (for
WUESR*/WUEMR*access) - If it should trigger on rising- or falling-edge
- The corresponding INTC IRQ
- The ISR to handle the event
- WUC group and bit offset (for
Alternatives
Time-triggered architecture
Strictly use timers as the interrupt source. Tasks would then be scheduled to run only at certain intervals.
Tasks that are considered critical or require a short turnaround time can be scheduled on the shortest interval.