В моем Linux C ++ проекте у меня есть область аппаратной памяти, отображенная где-то в физическом адресном пространстве , к которой я обращаюсь с помощью указателей uint32_t после mmap .
Выпуск сборки приложения завершается с SIGBUS (ошибка шины) .
Это происходит потому, что компилятор оптимизирует доступ к вышеупомянутой аппаратной памяти, используя 64-битный доступ , вместо того, чтобы придерживаться 32-битной => ошибки шины, доступ к аппаратной памяти возможен только с использованием 32-битной читает / пишет .
Я пометил указатель uint32_t как volatile .
Работает. Для этой определенной c части кода не менее . Потому что компилятору сказано не делать переупорядочение. И большую часть времени пришлось бы менять порядок для оптимизации.
Я знаю, что volatile контролирует , когда компилятор обращается к памяти. Вопрос в следующем: volatile также сообщает компилятору , как получить доступ к памяти, то есть , чтобы получить к нему доступ именно так, как программист указывает ? Я гарантирую, что компилятор всегда будет придерживаться 32-битного доступа к энергозависимым буферам uint32_t?
Например, гарантирует ли volatile то, что компилятор будет обращаться к 2 последовательных операций записи к 2 последовательным 32-битным значениям в следующем фрагменте кода, используя также 32-битные операции чтения / записи?
void aFunction(volatile uint32_t* hwmem_array)
{
[...]
// Are we guaranteed by volatile that the following 2 consecutive writes, in consecutive memory regions
// are not merged into a single 64-bit write by the compiler?
hwmem_array[0] = 0x11223344u;
hwmem_array[1] = 0xaabbccddu;
[...]
}