中断锁,中断通知与调度锁

中断锁

禁止多线程访问临界区最简单的方式,就是通过关闭系统中断来保证当前操作不会被打断。
全局中断开关也称为中断锁。

RT-Thread中关闭全局中断的函数接口如下:

rt_base_t rt_hw_interrupt_disable(void) 禁掉所有中断并返回禁掉之前的中断状态
void rt_hw_interrupt_enable(rt_base_t level) 恢复禁掉之前的中断状态

说明:

  • 中断锁可以用于任何需要操作临界区的场合。中断锁对系统的实时性影响非常大,要慎重使用。当然,若使用得当,则会变成一种快速、高效的同步方式。
  • 使用中断锁最主要的问题在于,在中断关闭期间系统将不再响应任何中断,也就不能响应外部的事件。因此在使用中断锁时,需要确保关闭中断的时间非常短。比如常用来完成对某些全局变量的加减操作。
  • 函数 rt_hw_interrupt_disable() 和函数 rt_hw_interrupt_enable() 一般需要配对使用,从而保证正确的中断状态。

中断通知

当中断发生,进入中断处理函数时,需要通知内核当前已经进入到中断状态。可以调用如下接口函数:

/* 进入中断时,通知内核当前已经进入中断状态 */
void rt_interrupt_enter(void);
/* 退出中断时,用于通知内核当前已经退出中断状态 */
void rt_interrupt_leave(void);

注意 不要在应用程序中调用这两个函数。

使用 rt_interrupt_enter/leave() 的作用是,在中断服务程序中,如果调用了内核相关的函数(如释放信号量等操作),则可以通过判断当前中断状态,让内核及时调整相应的行为。
如果中断服务程序不会调用内核相关的函数(释放信号量等操作),也可以不调用 rt_interrupt_enter/leave()函数。
为了编程模式规范化,建议在每个ISR中加上中断通知功能。

调度器锁

/**
 * This function will lock the thread scheduler.
 */
void rt_enter_critical(void)

/**
 * This function will unlock the thread scheduler.
 */
void rt_exit_critical(void)

对调度器上锁,系统依然能响应外部中断,中断服务例程依然能进行相应的响应。

拓展问题

Q: 请教下 rt_enter_critical 和 rt_interrupt_enter 的区别
这两个函数的实现都调用了 rt_hw_interrupt_disable,为什么称 rt_enter_critical 为调度器锁? http://www.bubuko.com/infodetail-654022.html 这个帖子里说 “对调度器上锁,系统依然能响应外部中断,中断服务例程依然能进行相应的响应。”,调用了 rt_hw_interrupt_disable,应该也响应不了外部中断吧?
A:调用 rt_hw_interrupt_disable 仅是为了防止访问冲突,随后就成对调用了 rt_hw_interrupt_enable 了。

rt_enter_critical 的关键是 lock_nest++
rt_interrupt_enter 的关键是 rt_interrupt_nest++

posted @ 2023-03-29 18:58  海林的菜园子  阅读(207)  评论(0编辑  收藏  举报