Во встроенном C я пытаюсь создать общий способ безопасной передачи значения из моего ISR (передний план) в мой основной цикл (фон). Под «общим» я подразумеваю, что я не хочу приостанавливать прерывания (потому что это зависит от компилятора/ЦП и может иметь побочные эффекты), просто хочу делать это с флагами занятости и т. д. Для этого конкретного механизма мне не нужно очередь, я просто хочу получить самое последнее значение, сообщенное ISR.
Таким образом, шаблон, который я использую, представляет собой структуру и несколько функций, которые работают со структурой. Проблема, конечно, в том, что функция «записи» основана на ISR и может прервать функцию «чтения» в любое время, и я хочу исключить возможность повреждения данных. Подход представляет собой двухслотовую систему и пару флагов занятости.
Это будет работать? И/или есть более простой способ? (Помните, что это встроенный C, и я пытаюсь быть универсальным/переносимым.) Спасибо!
typedef struct
{
uint8_t busy;
int32_t valueA;
int32_t valueB;
uint8_t reading_from_A;
uint8_t last_wrote_to_B;
} sSafeI32_Fore2Back;
void SafeI32_InitFore2Back(sSafeI32_Fore2Back * si)
{
si->busy = 0;
si->valueA = 0;
si->valueB = 0;
si->reading_from_A = 0;
si->last_wrote_to_B = 1;
}
int32_t SafeI32_ReadFromBack(sSafeI32_Fore2Back * si)
{
int32_t rtn;
si->busy = 1;
if (si->last_wrote_to_B)
{
rtn = si->valueB;
}
else
{
si->reading_from_A = 1;
rtn = si->valueA;
si->reading_from_A = 0;
}
si->busy = 0;
return rtn;
}
void SafeI32_WriteFromFore(sSafeI32_Fore2Back * si, int32_t v)
{
if (si->busy == 0)
{
si->valueA = v;
si->last_wrote_to_B = 0;
}
else
{
if (si->reading_from_A)
{
si->valueB = v;
si->last_wrote_to_B = 1;
}
else
{
si->valueA = v;
si->last_wrote_to_B = 0;
}
}
}