简体   繁体   English

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

[英]Atomic operation in multithreaded embedded software

I have been developing an RTOS based embedded software in C and I have encountered a problem regarding shared resource access from several threads. 我正在用C开发基于RTOS的嵌入式软件,并且遇到了有关从多个线程访问共享资源的问题。 I have two problems. 我有两个问题。 The first one is seting and getting a value of state variable in state machine. 第一个是在状态机中设置并获取状态变量的值。 Below is the header file for StateMachine "object": 以下是StateMachine“对象”的头文件:

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);

The implementation of the access methods is following: 访问方法的实现如下:

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

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

My problem is that I am not sure whether I should use a mutex for controlling the access to state variable. 我的问题是我不确定是否应该使用互斥体来控制对状态变量的访问。 I meant that reading and writing of 32 bit variable on 32 bit MCU is atomic operation. 我的意思是在32位MCU上读写32位变量是原子操作。

The second problem regards reading the value of one item of an array containing the unsigned 32 bits integers where each bit stores a value of one bit variable. 第二个问题是读取包含无符号32位整数的数组的一项的值,其中每个位存储一个位变量的值。 Here again I am not sure whether it is necessary to use a mutex. 再次在这里我不确定是否需要使用互斥锁。 From the same reason as above I think no but I would like to hear an opinion of some more experienced programmer. 基于与上述相同的原因,我想不,但我想听听一些更有经验的程序员的意见。 The associated header file for bits array "object": 位数组“对象”的关联头文件:

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

extern uint32_t GetWordValue(BitsArray*, uint8_t);

The access method implementation: 访问方法的实现:

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

Thank you for any ideas. 谢谢您的任何想法。

Both of your questions is the same problem really. 您的两个问题确实是同一个问题。

32 bit MCU means nothing unless you disassemble the code and verify that the operation is indeed a single instruction . 除非您反汇编代码并确认操作确实是一条指令 ,否则32位MCU毫无意义。 This is often not the case with C code. C代码通常不是这种情况。

Often you have 2 or more instructions like: "load value from stack into register", "do stuff with register", in which case it doesn't matter how many bits your MCU got. 通常,您有2条或更多条指令,例如:“将堆栈中的值加载到寄存器中”,“用寄存器执行操作”,在这种情况下,您的MCU获得多少位无关紧要。 You can get an interrupt or context switch in between the two instructions. 您可以在两条指令之间进行中断或上下文切换。

And even if you can verify that the machine code is atomic, that's not necessarily a stable state of affairs. 即使您可以验证机器代码是原子的,也不一定是稳定的状态。 Make changes to the code, add more variables, link again, and suddenly code that was atomic before is atomic no longer, or vice versa. 更改代码,添加更多变量,再次链接,突然之间以前是原子的代码不再是原子的,反之亦然。

C simply has no guarantee of atomicity. C根本无法保证原子性。 Some alternatives if you don't trust the disassembly: 如果您不信任反汇编,则可以选择以下几种方法:

  • C11 _Atomic . C11 _Atomic
  • Write inline assembler. 编写内联汇编器。
  • Use a mutex or similar synchronization mechanism. 使用互斥或​​类似的同步机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM