Прошивка разработчика здесь. Это стандартная проблема во встроенном программировании, которая ставит в тупик многих (даже очень опытных) разработчиков.
Я предполагаю, что вы пытаетесь получить доступ к аппаратному регистру, и это значение регистра может со временем изменяться (будь то состояние прерывания, таймер, индикация GPIO и т. Д.).
Ключевое слово volatile
является лишь частью решения, и во многих случаях может не потребоваться. Это приводит к тому, что переменная будет перечитываться из памяти каждый раз, когда она используется (в отличие от оптимизации компилятором или сохранения в регистре процессора при многократном использовании), но не является ли " память " читаемая информация является фактическим аппаратным регистром, в отличие от кэшированного местоположения, которое неизвестно вашему коду и не зависит от ключевого слова volatile
. Если ваша функция читает регистр только один раз, то вы, вероятно, можете отключить volatile
, но, как правило, я предлагаю, чтобы большинство аппаратных регистров было определено как volatile
.
Большая проблема - кеширование и когерентность кеша. Самый простой подход - убедиться, что ваш регистр находится в не кэшированном адресном пространстве. Это означает, что каждый раз, когда вы получаете доступ к регистру, вы гарантированно читаете / записываете фактический аппаратный регистр, а не кэш-память. Более сложный, но потенциально более эффективный подход состоит в том, чтобы использовать кэшированное адресное пространство и заставить ваш код вручную принудительно обновлять кеш для определенных ситуаций, подобных этой. Для обоих подходов то, как это достигается, зависит от архитектуры и выходит за рамки вопроса. Это может включать MTRR (для x86), MMU, модификации таблицы страниц и т. Д.
Надеюсь, это поможет. Если я что-то пропустил, дайте мне знать, и я расширю свой ответ.