Барьеры памяти связаны с порядком доступа к памяти, но вы также должны убедиться, что значения не остаются в регистрах, а вообще записываются в память.
Единственный способ добиться этого с помощью компилятора TI — использовать volatile
.
Обратите внимание, что volatile
, будучи модификатором переменной, в своей реализации касается не самой переменной (т.е. ее памяти), а всех доступов к этой переменной. Поэтому, если вы хотите избежать эффектов слишком малой оптимизации, напишите свою программу так, чтобы только некоторые обращения к переменным были изменчивыми.
Для этого объявите свои переменные как обычно и добавляйте volatile
только тогда, когда вы хотите принудительно прочитать или записать переменную. Вы можете использовать вспомогательные функции следующим образом:
inline void force_write(int *ptr, int value)
{
*(volatile int *)ptr = value;
}
или используйте этот отличный макрос, украденный из Linux, который можно использовать как для чтения/записи, так и для всех типов:
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
...
if (ACCESS_ONCE(ready) != 0)
ACCESS_ONCE(new_data) = 42;
(Название имеет исторические причины; лучше назовите его FORCE_ACCESS
.)
person
CL.
schedule
17.10.2012
asm
в статическую встроенную функцию, возвращающую значение, которое вы хотите обновить? - person unixsmurf   schedule 09.10.2012volatile
, кажется, работает, но я хочу его избежать, так как это предотвратит слишком много оптимизаций компилятора. - person starblue   schedule 09.10.2012float*
иint*
не указывают на одну и ту же область памяти. Таким образом, компилятор может сгенерировать двоичный файл с неправильным поведением. - person qehgt   schedule 17.10.2012volatile
? Компилятор ничего не знает о ваших обработчиках прерываний, поэтому он может оптимизировать весь доступ к вашим глобальным данным (и у него есть на это права). - person qehgt   schedule 17.10.2012volatile
. Но, как я писал выше, я хочу избежать этого, потому что это предотвратит слишком много оптимизаций компилятором. - person starblue   schedule 17.10.2012volatile
. Только частьstruct
может быть объявлена какvolatile
. Кроме того, вы можете выполнять необходимые операции чтения/записи через другой указательvolatile
, но в этом случае вы должны быть очень осторожны. - person qehgt   schedule 17.10.2012asm("")
(с пустой строкой), чтобы заставить компилятор завершить все пост-эффекты. Он использовался давно с очень старой версией компилятора TI. Но можно проверить, может еще работает. Просто поместите этоasm("");
до и после необходимых операций чтения и записи. - person qehgt   schedule 17.10.2012