Код для обработчика службы прерываний:
volatile unsigned char x = 0;
void interruptHandler() __attribute__ ((signal));
void interruptHandler() {
f();
g();
}
Вызовы:
void f() { x ++; } // could be more complex, could also be in a different file
void g() { x ++; } // as `f()`, this is just a very simple example
Поскольку x
- переменная переменная, она читается и записывается при каждом ее использовании.Тело обработчика прерываний компилируется в (avr-gcc -g -c -Wa,-alh -mmcu=atmega328p -Ofast file.c
):
lds r24,x
subi r24,lo8(-(1))
sts x,r24
lds r24,x
subi r24,lo8(-(1))
sts x,r24
Теперь я могу вручную встроить функции и использовать временную переменную:
unsigned char y = x;
y ++;
y ++;
x = y;
Или я могу просто написать:
x += 2;
Оба примера компилируются с гораздо более эффективными:
lds r24,x
subi r24,lo8(-(2))
sts x,r24
Можно ли сказать avr-gcc
, чтобы оптимизировать доступ к переменным переменным внутри interruptHandler
то есть, чтобы выполнить мою ручную оптимизацию автоматически?
В конце концов, пока работает interruptHandler
, глобальные прерывания отключены, и x
невозможно изменить.Я предпочитаю не выполнять оптимизацию кода вручную, возможно создавая дублирующийся код (если f()
и g()
необходимы в другом месте) и внося ошибки.