没志青年
发布于 2025-07-28 / 15 阅读
0

RT-Thread 中断管理

中断管理

为了把操作系统和系统底层的异常、中断硬件隔离开来,RT-Thread 把中断和异常封装为一组抽象接口,如下图所示:

rt_interrupt_enter()rt_interrupt_leave():用于在中断服务程序进入和离开时通知内核中断上下文的切换。

中断服务程序注册

rt_isr_handler_t rt_hw_interrupt_install ( int vector,
                                           rt_isr_handler_t  handler,
                                           void *param,
                                           char *name );

  • vector:中断号

  • handler:中断服务程序

  • param:传给中断服务程序的参数

  • name:中断名称

中断服务程序:

static void irq_callback(void *args)
{
    rt_interrupt_enter();

    rt_sem_release(irq_sem);  /* 释放信号量唤醒线程 */
   
    rt_interrupt_leave();
}
  • 如果调用了内核的函数,必须添加 rt_interrupt_enter/leave()

  • 如果没调用内核的函数,不需要添加。

  • 不能调用会导致阻塞的函数。

如果是 DMA 等这种不需要调用 RT-Thread 内核函数的硬件中断,直接像裸机一样使用就行了,使用 NVIC 注册和使能。(不确定,待实验。)

void DMA1_Channel1_IRQHandler(void)
{
    __HAL_DMA_CLEAR_FLAG(&hdma_adc1, DMA_FLAG_TC1);
}

中断使能与屏蔽

屏蔽中断源:

void rt_hw_interrupt_mask(int vector);

使能中断源:

void rt_hw_interrupt_umask(int vector);

vector 为中断号。

全局中断开关

用于保护临界资源,是一种强大和高效的互斥机制,缺点是关中断时间长会影响系统的实时性。

关中断,线程暂停调度,当前线程独占 CPU。

关闭全局中断:

rt_base_t rt_hw_interrupt_disable(void);
  • 返回值:返回之前的中断状态。

打开全局中断:

void rt_hw_interrupt_enable(rt_base_t level);
  • level:恢复中断关闭前的状态。

这两个函数需配对使用:

/* 关闭中断 */
level = rt_hw_interrupt_disable();

/* 执行互斥操作 */
a = a + value;

/* 恢复中断 */
rt_hw_interrupt_enable(level);

开关全局中断的 API 支持多级嵌套使用,比如:

void global_interrupt_demo(void)
{
    rt_base_t level0;
    rt_base_t level1;
  
    level0 = rt_hw_interrupt_disable();
    level1 = rt_hw_interrupt_disable();

    // 执行函数功能...

    rt_hw_interrupt_enable(level1);   // 注意开中断的顺序
    rt_hw_interrupt_enable(level0);
}

这样做的好处是,假设有一个函数:

void func_a(void)
{
    rt_base_t level0;
  
    level0 = rt_hw_interrupt_disable();
 
    // 执行函数功能...

    rt_hw_interrupt_enable(level0);
}

需要被其它函数调用:

void func_b(void)
{
    func_a();

    // 执行函数功能...
}


void func_c(void)
{
    rt_base_t level0;
  
    level0 = rt_hw_interrupt_disable();
 
    func_a();    // 这样做也没问题
    
    // 执行函数功能...

    rt_hw_interrupt_enable(level0);
}

这个特性可以给开发带来很大的便利,不需要考虑多次开关中断带来的中断状态不确定问题。