Interrupt Management
Categories:
3 minute read
Exceptions and Interrupts
XWOS classifies interrupts into EXC and IRQ:
- EXC refers to interrupts defined by the architecture, called Exceptions in some architectures, with negative interrupt numbers;
- IRQ refers to peripheral interrupts, such as UART interrupts, etc., with interrupt numbers represented as 0 and positive values.
Kernel Interrupts
XWOS kernel interrupts include:
- Context switch interrupt: used to switch threads;
- Tick timer interrupt: used to provide periodic timer interrupts;
- Scheduler service interrupt: used to start scheduling, exit threads, freeze threads, power management, and other operations.
Interrupt Priority
XWOS requirements for interrupt priority:
Context switch interrupt is the lowest priority interrupt in the system
Context switch interrupt <= Tick timer interrupt <= Scheduler service interrupt
CPU Interrupt Control
A CPU can only operate its own interrupt control, not the interrupts of other CPUs. The following functions affect whichever CPU they run on:
xwos_cpuirq_enable_lc(): Enable local CPU interrupts (non-nestable)xwos_cpuirq_disable_lc(): Disable local CPU interrupts (non-nestable)xwos_cpuirq_save_lc(): Save then disable local CPU interrupt state (nestable)xwos_cpuirq_restore_lc(): Restore local CPU interrupt state (nestable)xwos_cpuirq_suspend_lc(): Suspend local CPU interrupts (nestable)xwos_cpuirq_resume_lc(): Resume local CPU interrupts (nestable)xwos_cpuirq_test_lc(): Test local CPU interrupt state
When porting XWOS to a specific chip, the OS porting implementation layer (XWOSIMPL) must provide the concrete implementation of the above functions:
- Source files:
xwosimpl_irq.h/xwosimpl_irq.cxwospl_cpuirq_enable_lc(): corresponds toxwos_cpuirq_enable_lc()xwospl_cpuirq_disable_lc(): corresponds toxwos_cpuirq_disable_lc()xwospl_cpuirq_save_lc(): corresponds toxwos_cpuirq_save_lc()xwospl_cpuirq_restore_lc(): corresponds toxwos_cpuirq_restore_lc()xwospl_cpuirq_test_lc(): corresponds toxwos_cpuirq_test_lc()
Usage Limitations
Disabling and enabling the CPU global interrupt control must ensure that nesting does not occur. For example, the following nested code is incorrect because when critical section 1 ends, it will unexpectedly enable CPU interrupts, thus failing to guarantee the safety of critical section 0:
void func1(void)
{
xwos_cpuirq_disable_lc();
/* ... critical section 1 ... */
xwos_cpuirq_enable_lc();
}
void func0(void)
{
xwos_cpuirq_disable_lc();
/* ... critical section 0 ... */
func1(); /* ERROR!!! nesting occurs */
/* CPU interrupts are unexpectedly enabled here */
/* ... critical section 0 ... */
xwos_cpuirq_enable_lc();
}
When interrupt-disable code nests, the CPU global interrupt state must be saved and restored. The above example can be corrected to:
void func1(void)
{
xwreg_t cpuirq;
xwos_cpuirq_save_lc(&cpuirq);
/* ... critical section 1 ... */
xwos_cpuirq_restore_lc(cpuirq);
}
void func0(void)
{
xwreg_t cpuirq;
xwos_cpuirq_save_lc(&cpuirq);
/* ... critical section 0 ... */
func1();
/* ... critical section 0 ... */
xwos_cpuirq_restore_lc(cpuirq);
}
The Suspend/Resume versions of CAPI can also be used:
void func1(void)
{
xwos_cpuirq_suspend_lc(&cpuirq);
/* ... critical section 1 ... */
xwos_cpuirq_resume_lc(cpuirq);
}
void func0(void)
{
xwos_cpuirq_suspend_lc(&cpuirq);
/* ... critical section 0 ... */
func1();
/* ... critical section 0 ... */
xwos_cpuirq_resume_lc(cpuirq);
}
Peripheral Interrupts
Getting the Current Code’s Interrupt Number
XWOS provides CAPI xwos_irq_get_id() to obtain the interrupt number of the current interrupt.
If this CAPI is used outside an interrupt context, it returns an error code:
-ENOTISRCTX: current context is not an interrupt
Therefore, this CAPI can also be used to determine whether the current context is an interrupt context.
When porting XWOS to a specific chip, the OS porting implementation layer (XWOSIMPL) must provide the implementation of the above function:
- Source files:
xwosimpl_irq.h/xwosimpl_irq.cxwospl_irq_get_id(): corresponds toxwos_irq_get_id()
Other Peripheral Interrupt CAPI
xwos_irq_enable(): Enable a specific peripheral interruptxwos_irq_disable(): Disable a specific peripheral interruptxwos_irq_save(): Save the state of a peripheral interrupt, then disable itxwos_irq_restore(): Restore the state of a peripheral interrupt
When porting XWOS to a specific chip, the OS porting implementation layer (XWOSIMPL) must provide the implementation of the above functions:
- Source files:
xwosimpl_irq.h/xwosimpl_irq.cxwospl_irq_enable(): corresponds toxwos_irq_enable()xwospl_irq_disable(): corresponds toxwos_irq_disable()xwospl_irq_save(): corresponds toxwos_irq_save()xwospl_irq_restore(): corresponds toxwos_irq_restore()