2013-12-02 4 views
2

В настоящее время я работаю с Altera Nios II, и это дает мне возможность, например, подключить все красные светодиоды к int * с заданным адресом памяти. Во всех примерах это выглядит следующим образом:Необходимость ключевого слова volatile при определении указателя с жестким адресом

volatile int * ledR = (int*) 0x00093050; 

Это всегда префикс ключевого слова volatile, почему? Насколько я знаю, ключевое слово volatile только говорит компилятору ничего не понимать о переменной, но компиляция не просто предполагает, что этот указатель должен быть удален, не так ли?

ответ

4

В основном, имея дело с аппаратными регистрами, нам нужно использовать ключевое слово volatile. Это заставляет компилятор запрашивать регистр каждый раз, когда вы вызываете адрес, вместо того, чтобы использовать локальную копию этой переменной.

0

Существует бесчисленное множество чтения в Интернете о том, как работает летучее ключевое слово ...

Он всегда приставка с летучим ключевым словом, почему?

Поскольку код должен считывать/записывать значение фактического регистра оборудования. Если не для volatile, оптимизатор может решить прочитать аппаратный регистр, а затем сохранить значение в локальной переменной в ОЗУ, а затем использовать эту переменную с этого момента всякий раз, когда вы пытаетесь получить доступ к регистру. Это, разумеется, сломало бы всю программу. Есть много подобных ошибок, которые может вызвать оптимизатор.

Таким образом, ключевое слово volatile сообщает компилятору, что ему не разрешено выполнять какие-либо оптимизации, связанные с конкретной переменной.

1
volatile int * ledR = (int*) 0x00093050; 

volatile в заявлении выше говорит компилятору, что значение по адресу 0x00093050 не кэшируются. Здесь volatile не предназначен для указателя, он предназначен для значения по адресу, который удерживается указателем.

2

заставляет компилятор фактически выполнять операции над объектом volatile, даже если это может показаться ненужным. В вашем примере volatile относится к объекту, на который указывает.

Для регистров:

  • заставляет чтение фактического регистра. Если вы несколько раз читаете идентификатор volatile, то сколько раз будет считываться регистр HW. Нет кэширования в локальной переменной. Это может быть важно по нескольким причинам: значение (например, GPIO) может измениться, некоторые регистры имеют специальные действия при чтении.

  • он заставляет писать. Если вы пишете на адрес, но не повторно используете это содержимое, компилятор может в некоторых случаях подумать, что запись не нужна и вообще удаляет.

0

Многие компиляторы, используемые для лечения все объекты с жестко закодированными адресами, как volatile, так как в противном случае делать потребует дополнительной работы как компилятор и человека, использующего его, предлагая при этом мало пользы.Любой, кто пишет компилятор для встроенного или системного программирования, будет, как минимум, включать в себя режим, который рассматривает все жестко запрограммированные выборки как изменчивые, учитывая корпус кода, который опускал ключевое слово для краткости, прежде чем компиляторы начали его требовать, но всем, кто пишет код для встроенных систем, было бы рекомендовано включить volatile во все декларации регистра жесткого кодирования, чтобы обеспечить правильное поведение с компиляторами, которые пытаются консолидировать операции с жестко закодированными адресами.

Смежные вопросы