原子变量是线程和 ISR 可以不间断地读取和修改的变量。它在 32 位计算机上为 32 位,在 64 位计算机上为 64 位。
概念
可以定义任意数量的原子变量(仅受可用 RAM 的限制)。
使用内核的原子 API 操作原子变量可以保证正确执行所需的操作,即使优先级较高的上下文操作同一变量也是如此。
内核还支持原子变量数组
中单个位
的原子操作。
定义原子变量
原子变量是使用atomic_t
类型定义变量。
默认情况下,原子变量初始化为零。但是,可以使用ATOMIC_INIT
为其指定不同的值:
atomic_t flags = ATOMIC_INIT(0xFF);
操作原子变量
下面的代码演示如何使用原子变量来跟踪调用函数的次数。
atomic_t call_count;
int call_counting_routine(void)
{
/* increment invocation counter */
atomic_inc(&call_count);
/* do rest of routine's processing */
...
}
操作原子变量数组
下面的代码演示如何使用原子变量数组实现一组 200 个标志位。
#define NUM_FLAG_BITS 200
ATOMIC_DEFINE(flag_bits, NUM_FLAG_BITS);
/* set specified flag bit & return its previous value */
int set_flag_bit(int bit_position)
{
return (int)atomic_set_bit(flag_bits, bit_position);
}
原子变量的API
API | 描述 |
---|---|
atomic_test_bit | 测试是否设置了目标的位。目标可以是单个原子变量或原子变量数组。 |
atomic_test_and_clear_bit | 判定原子变量的位,并且清除该位 |
atomic_test_and_set_bit | 判定原子变量的位,并且设置该位 |
atomic_clear_bit | 清除原子变量的位 |
atomic_set_bit | 设置原子变量的位 |
atomic_set_bit_to | 以原子方式将位设置为给定值 |
atomic_cas | 在目标上执行原子比较和设置。如果目标的当前值等于old_value,则目标设置为new_value。如果目标的当前值不等于old_value,则目标保持不变。 |
atomic_ptr_cas | 在目标上执行原子指针的比较和设置。如果目标的当前值等于old_value,则目标设置为new_value。如果目标的当前值不等于old_value,则目标保持不变。 |
atomic_add | 原子相加 |
atomic_sub | 原子相减 |
atomic_inc | 原子自增 |
atomic_dec | 原子自减 |
atomic_get | 获取原子值 |
atomic_ptr_get | 获取原子指针值 |
atomic_set | 原子设置值 |
atomic_ptr_set | 原子指针设置值 |
atomic_clear | 清空原子值 |
atomic_ptr_clear | 清空原子指针值 |
atomic_or | 原子按位或 |
atomic_xor | 原子按位异或 |
atomic_and | 原子按位与 |
atomic_nand | 原子按位与取反 |