Определение обработчика прерываний

Директива #pragma interrupt должна непосредственно предшествовать реализации функции, например:

#pragma interrupt void SPORT0_Receive_Handler(int sig);

void SPORT0_Receive_Handler(int sig)

{

int a;

...

return;

}

Эта директива указывает компилятору на то, что функция должна быть скомпилирована не как подпрограмма, а как обработчик прерывания. В частности, это приводит к тому, что все регистры (в том числе Scratch-регистры) должны быть сохранены и восстановлены при выходе из обработчика – это отличие от обычной процедуры. Выход из процедуры по rti, а не как из С-функции по jump.

Эту директиву необходимо использовать только с диспетчерами, зарегистрированными функциями interruptss() и signalss().

Особенности организации доступа к данным в С-модулях в программах с прерываниями

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

int a, b, c, d;

...

c = x+a+b;

... // код не меняющий ни x, ни a

d = x+a;

Здесь (x+a) - общее подвыражение, и при вычислении переменной с компилятор сохраняет его в каком-либо временном регистре, чтобы затем подставить при вычислении переменной d, поскольку "видит", что между этими двумя выражениями x не изменялся. Если же если переменная x объявлена как volatile, то компилятор скорее всего не будет его оптимизировать.

Другой пример.

while (x<5) {

// что-то не меняющее x

};

Здесь очевидно, что условие цикла, не будь x – volatile, не меняется. То есть его можно "соптимизировать", вынеся лишние вычисления из цикла

if (x<5)

while(1) {

//....

}

Если же x – volatile, то компилятор такой оптимизации делать не будет.

Исходный текст программы Код, сгенерированный компилятором
int x=1; int y=2; int z=3; int a,b; ... a = x+y+z; b = x+y; r2=6; r12=3; dm(_a)=r2; dm(_b)=r12;
volatile int x=1; int y=2; int z=3; int a,b; ... a = x+y+z; b = x+y; r2=dm(_x.0); r12=5; r2=r2+r12; dm(_a)=r2; r12=dm(_x.0); r8=2; r12=r12+r8; dm(_b)=r12;

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: