1. RT-Thread中的临界资源保护概述
在实时操作系统(RT-Thread)开发中,临界资源保护是确保系统稳定性的关键机制。所谓临界资源,指的是那些可能被多个线程或中断服务程序(ISR)同时访问的共享资源。当这类资源在没有保护措施的情况下被并发访问时,极有可能导致数据竞争、状态不一致等严重问题。
RT-Thread提供了多种保护临界资源的机制,包括:
- 关闭中断
- 调度器锁
- 互斥量(mutex)
- 信号量(semaphore)
- 自旋锁(spinlock)
其中,关闭中断是最彻底但也最"暴力"的保护方式。它会暂时屏蔽所有中断(或特定优先级的中断),确保当前执行流程不会被中断服务程序打断。这种方式虽然简单直接,但会显著影响系统的实时性,因此必须谨慎使用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 必须使用中断保护的临界资源类型
2.1 硬件寄存器操作
当直接操作硬件寄存器时,特别是那些控制关键外设(如定时器、DMA控制器、通信接口等)的寄存器,通常需要关闭中断保护。这是因为:
- 寄存器操作往往需要多个步骤完成
- 硬件状态可能在操作过程中被中断改变
- 某些寄存器写入可能有严格的时序要求
例如,配置STM32的定时器时:
c复制/* 定时器配置临界区 */
rt_base_t level = rt_hw_interrupt_disable();
TIM1->ARR = 1000; // 设置自动重装载值
TIM1->PSC = 72; // 设置预分频器
TIM1->CR1 |= TIM_CR1_CEN; // 启动定时器
rt_hw_interrupt_enable(level);
如果不关闭中断,可能在ARR和PSC设置之间被中断打断,导致定时器产生错误的周期。
2.2 全局变量与中断共享数据
当全局变量既会被普通线程访问,又会在中断服务程序中被修改时,必须使用中断保护。这是因为:
- 编译器可能对普通变量的访问进行优化
- 某些架构上变量访问不是原子操作
- 中断可能在任何时候打断普通线程的执行
典型场景是中断计数器:
c复制volatile uint32_t irq_count = 0;
void some_isr(void)
{
irq_count++;
}
uint32_t get_count(void)
{
rt_base_t level;
uint32_t count;
level = rt_hw_interrupt_disable();
count = irq_count;
rt_hw_interrupt_enable(level);
return count;
}
即使irq_count被声明为volatile,在32位架构上读取64位变量仍然可能需要多条指令,因此需要保护。
