Примечание: вы можете использовать, например, «регистры FPU» для атомарной модификации (если вам это действительно нужно), но вы должны скрыть от компилятора и ОСРВ, что архитектура имеет FPU.
ипы данных на микроконтроллерах STM32:http://www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm.
Эти микроконтроллеры используют 32-битные процессоры с ядром ARM.
Какие типы данных имеют автоматическое атомарное чтение и атомарную запись?
Я почти уверен, что все 32-битные типы данных это делают (поскольку процессор 32-битный), а все 64-битные типы данных - нет (так как для чтения или записи 64-битного слова потребуется как минимум 2 процессора). ), но что насчетbool
(1 байт) иuint16_t
/int16_t
(2 байта)?
Контекст: я разделяю переменные между несколькими потоками (одно ядро, но несколько потоков или «задачи», как они называются, вFreeRTOS) на STM32, и мне нужно знать, нужно ли принудительно использовать атомарный доступ, отключая прерывания, используя мьютексы и т. д.
ОБНОВИТЬ:
Ссылаясь на этот пример кода:
volatile bool shared_bool;
volatile uint8_t shared u8;
volatile uint16_t shared_u16;
volatile uint32_t shared_u32;
volatile uint64_t shared_u64;
volatile float shared_f; // 32-bits
volatile double shared_d; // 64-bits
// Task (thread) 1
while (1)
{
// Write to the values in this thread.
// What I write to each variable will vary. Since other threads
// are reading these values, I need to ensure my *writes* are atomic, or else
// I must use a mutex to prevent another thread from reading a variable in the middle
// of this thread's writing.
shared_bool = true;
shared_u8 = 129;
shared_u16 = 10108;
shared_u32 = 130890;
shared_f = 1083.108;
shared_d = 382.10830;
}
// Task (thread) 2
while (1)
{
// Read from the values in this thread.
// What thread 1 writes into these values can change at any time, so I need to ensure
// my *reads* are atomic, or else I'll need to use a mutex to prevent the other
// thread from writing to a variable in the midst of reading
// it in this thread.
if (shared_bool == whatever)
{
// do something
}
if (shared_u8 == whatever)
{
// do something
}
if (shared_u16 == whatever)
{
// do something
}
if (shared_u32 == whatever)
{
// do something
}
if (shared_u64 == whatever)
{
// do something
}
if (shared_f == whatever)
{
// do something
}
if (shared_d == whatever)
{
// do something
}
}
В приведенном выше коде, для каких переменных я могу сделать это без использования мьютекса? Мое подозрение заключается в следующем:
volatile bool
: безопасно - мьютекс не требуетсяvolatile uint8_t
: безопасно - мьютекс не требуетсяvolatile uint16_t
: безопасно - мьютекс не требуетсяvolatile uint32_t
: безопасно - мьютекс не требуетсяvolatile uint64_t
: Небезопасно - вы должны использовать критический раздел или MUTEX!volatile float
: безопасно - мьютекс не требуетсяvolatile double
: Небезопасно - вы должны использовать критический раздел или MUTEX!Пример критического раздела с FreeRTOS:
- https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html
// Force atomic access with these critical section atomic access guards.
taskENTER_CRITICAL();
// do the (now guaranteed to be safe) read or write here
taskEXIT_CRITICAL();
Связанные, но не отвечая на мой вопрос:Атомные операции в ARMARM: это запись / чтение из int atomic?(Мой собственный вопрос и ответ об атомарности в 8-битных микроконтроллерах AVR [и Arduino]):https://stackoverflow.com/a/39693278/4561887