RT-Thread临界区保护方法:
一、禁用全局中断
系统的线程调度是基于中断的,所以禁用中断即可实现阻止线程之间的切换。
在多线程访问同一个变量时,使用开关全局中断对该变量进行保护。
/* 同时访问的全局变量 */
static rt_uint32_t cnt;
void thread_entry(void *parameter)
{
rt_uint32_t no;
rt_uint32_t level;
no = (rt_uint32_t) parameter;
while (1)
{
/* 关闭全局中断 */
level = rt_hw_interrupt_disable();
cnt += no;
/* 恢复全局中断 */
rt_hw_interrupt_enable(level);
rt_kprintf("protect thread[%d]'s counter is %d\n", no, cnt);
rt_thread_mdelay(no * 10);
}
}
二、禁用系统调度器
将系统线程调度器禁用,直到临界区相关线程执行结束,再将调度器解锁,即可实现对临界区的保护。
void rt_enter_critical(void); /* 进入临界区*/
调用这个函数后,调度器将被上锁。在系统锁住调度器的期间,系统依然响应中断,如果中断唤醒了的更高优先级线程,调度器并不会立刻执行它,直到调用解锁调度器函数才尝试进行下一次调度。
void rt_exit_critical(void); /* 退出临界区*/
当系统退出临界区的时候,系统会计算当前是否有更高优先级的线程就绪,如果有比当前线程更高优先级的线程就绪,将切换到这个高优先级线程中执行;如果无更高优先级线程就绪,将继续执行当前任务。
void thread_entry(void* parameter)
{
while(1)
{
rt_enter_critical(); /* 将线程调度器上锁,此时线程调度器仅能响应中断 */
/* 以下进入临界区 */
. . . .
/*临界区执行完成*/
rt_exit_critical(); /* 调度器解锁 */
}
}
低功耗调试时,建议采用禁用系统调度方式,以保证系统以最低功耗进入休眠模式。