Цитата
Насколько мне известно, переменные длинее байта обновляются не за одну команду МК.
Нет, зависит от архитектуры.
Цитата
Имеет право на жизнь такая конструкция или чего-то не учел?
Не учел. Представь такую ситуацию: функция get вызывается из фона, проверяется флаг busy. Так как он равен нулю, то осуществляется переход к return. Чтобы возвратить 64-битное значение нужно скопировать его из памяти в регистры R0 и R1. Копирование происходит по 32 бита. Одна часть скопировалась. Тут происходит прерывание в котором вызывается inc, которая увеличивает значение счетчика. Прерывание завершается и управление возвращается get, которая копирует оставшиеся 32 бита, потенциально изменившиеся в прерывании. В итоге получается хрень.
Если используешь RTOS - применяй идущие в комплекте примитивы синхронизации. Если программка простая, без RTOS, то самый легкий и надежный способ - запрещать прерывания при чтении и изменении счетчика.
Код
static uint64_t counter;
void inc(uint32_t value)
{
__disable_interrupt();
counter += value;
__enable_interrupt();
}
uint64_t get(void)
{
__disable_interrupt();
uint64_t copy = counter;
__enable_interrupt();
return copy;
}