中断管理

XWOS的中断控制

异常与中断

XWOS将中断分为EXC和IRQ:

  • EXC是指架构中定义的中断,在某些架构中被称为 异常(Exception) ,中断号用负数表示;
  • IRQ是指外设中断,例如UART的中断等,中断号用 0正数 表示。

内核中断

XWOS内核的中断包括:

  • 切换上下文的中断:用于切换线程;
  • 滴答定时器的中断:用于提供周期性定时中断;
  • 调度器服务中断:用于启动调度、退出线程、冻结线程、电源管理等其他操作。

中断优先级

XWOS对中断优先级的要求:

切换上下文的中断为系统中最低优先级中断
切换上下文的中断 <= 滴答定时器的中断 <= 调度器服务中断

CPU中断开关

CPU只能操作自身的中断开关,不可操作其他CPU的中断。下面的函数运行在哪个CPU,就对哪个CPU起作用:

为某个芯片移植XWOS时,需要在操作系统移植实现层(XWOSIMPL)中给出上述函数的具体实现方法:

  • 源文件: xwosimpl_irq.h/xwosimpl_irq.c
    • xwospl_cpuirq_enable_lc() :对应于 xwos_cpuirq_enable_lc()
    • xwospl_cpuirq_disable_lc() :对应于 xwos_cpuirq_disable_lc()
    • xwospl_cpuirq_save_lc() :对应于 xwos_cpuirq_save_lc()
    • xwospl_cpuirq_restore_lc() :对应于 xwos_cpuirq_restore_lc()
    • xwospl_cpuirq_test_lc() :对应于 xwos_cpuirq_test_lc()

使用局限

关闭与开启CPU总中断开关需要确保不会发生嵌套,例如下面的嵌套代码是 错误 的,因为 临界区1 结束时会意外地将CPU中断打开, 从而无法保证 临界区0 的安全性:

void func1(void)
{
        xwos_cpuirq_disable_lc();
        /* ... 临界区1 ... */
        xwos_cpuirq_enable_lc();
}

void func0(void)
{
        xwos_cpuirq_disable_lc();
        /* ... 临界区0 ... */
        func1(); /* 错误!!!发生嵌套 */
        /* 此处CPU中断被意外打开 */
        /* ... 临界区0 ... */
        xwos_cpuirq_enable_lc();
}

当关闭中断的代码发生嵌套时,需要保存与恢复CPU总中断开关,上面的例子可以更正为:

void func1(void)
{
        xwreg_t cpuirq;

        xwos_cpuirq_save_lc(&cpuirq);
        /* ... 临界区1 ... */
        xwos_cpuirq_restore_lc(cpuirq);
}

void func0(void)
{
        xwreg_t cpuirq;

        xwos_cpuirq_save_lc(&cpuirq);
        /* ... 临界区0 ... */
        func1();
        /* ... 临界区0 ... */
        xwos_cpuirq_restore_lc(cpuirq);
}

也可使用Suspend/Resume版本的CAPI:

void func1(void)
{
        xwos_cpuirq_suspend_lc(&cpuirq);
        /* ... 临界区1 ... */
        xwos_cpuirq_resume_lc(cpuirq);
}

void func0(void)
{
        xwos_cpuirq_suspend_lc(&cpuirq);
        /* ... 临界区0 ... */
        func1();
        /* ... 临界区0 ... */
        xwos_cpuirq_resume_lc(cpuirq);
}

外设中断

获取当前代码的中断号

XWOS提供CAPI xwos_irq_get_id() 可以获取当前中断的中断号。 如果不在中断内使用此CAPI,将返回错误码:

  • -ENOTISRCTX :当前上下文不为中断

因此,此CAPI还可用于判断是否为 中断上下文

为某个芯片移植XWOS时,需要操作系统移植实现层(XWOSIMPL)中给出上述函数的实现方法:

  • 源文件: xwosimpl_irq.h/xwosimpl_irq.c
    • xwospl_irq_get_id() :对应于 xwos_irq_get_id()

外设中断的其他CAPI

为某个芯片移植XWOS时,需要操作系统移植实现层(XWOSIMPL)中给出上述函数的实现方法:

  • 源文件: xwosimpl_irq.h/xwosimpl_irq.c
    • xwospl_irq_enable() :对应于 xwos_irq_enable()
    • xwospl_irq_disable() :对应于 xwos_irq_disable()
    • xwospl_irq_save() :对应于 xwos_irq_save()
    • xwospl_irq_restore() :对应于 xwos_irq_restore()

CAPI参考