多线程嵌入式软件中的原子操作

Atomic operation in multithreaded embedded software

我一直在用 C 语言开发基于 RTOS 的嵌入式软件,我遇到了有关从多个线程访问共享资源的问题。我有两个问题。第一个是在状态机中设置和获取状态变量的值。下面是 StateMachine "object":

的头文件
typedef enum{
  STATE_01,
  STATE_02,
  STATE_03,
  STATE_04
}state_e;

// state machine instance
typedef struct{
  state_e currState;
}StateMachine;

extern state_e GetState(StateMachine*);
extern void SetState(StateMachine*, state_e);

访问方法的实现如下:

state_e GetState(StateMachine *sm){
  return sm->currState;
}

void SetState(StateMachine *sm, state_e state){
  sm->currState = state;
}

我的问题是我不确定是否应该使用互斥锁来控制对状态变量的访问。我的意思是在32位单片机上读写32位变量是原子操作。

第二个问题是读取包含无符号 32 位整数的数组中的一项的值,其中每一位存储一位变量的值。 在这里我再次不确定是否有必要使用互斥体。出于与上述相同的原因,我认为不会,但我想听听一些更有经验的程序员的意见。位数组的关联头文件 "object":

typedef struct{
  uint32_t BitsArray[NO_WORDS];
}BitsArray;

extern uint32_t GetWordValue(BitsArray*, uint8_t);

访问方法实现:

uint32_t GetWordValue(BitsArray *ba, uint8_t word){
 return *(ba->BitsArray + word);
}

感谢您的任何想法。

你的两个问题其实是同一个问题。

32 位 MCU 没有任何意义,除非您反汇编代码并验证该操作确实是 单指令。 C 代码通常不是这种情况。

通常您有 2 条或更多条指令,例如:"load value from stack into register"、"do stuff with register",在这种情况下,您的 MCU 有多少位并不重要。您可以在两条指令之间进行中断或上下文切换。

即使您可以验证机器代码是原子的,这也不一定是稳定的状态。更改代码,添加更多变量,再次 link,突然之间以前是原子的代码不再是原子的,反之亦然。

C 根本无法保证原子性。如果您不信任反汇编,则有一些替代方案:

  • C11_Atomic
  • 编写内联汇编程序。
  • 使用互斥锁或类似的同步机制。