реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Сохранение контекста в прерываниях, IAR
MrYuran
сообщение May 15 2008, 05:42
Сообщение #16


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



моё глубоко закоренелое ИМХО - не надо в прерываниях вызывать никакие функции. Либо уж накрайняк inline и описывать в одном модуле.
А лучше всего всё-таки по приёму кинуть байт в буфер, выставить флаг и функцию запускать снаружи, тайм-аут можно засекать по переполнению таймера.
А создавать себе трудности и потом героически их преодолевать - это неотъемлемая черта русского менталитета...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 15 2008, 05:53
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(MrYuran @ May 15 2008, 07:42) *
моё глубоко закоренелое ИМХО - не надо в прерываниях вызывать никакие функции.

Уточнение - для AVR - обязательно, если это только не очень "тяжелый обработчик" и без того использущий массу регистров. Рассуждения на эту тему добавил в свой предыдущий пост.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 15 2008, 06:36
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(zltigo @ May 15 2008, 08:53) *
Уточнение - для AVR - обязательно, если это только не очень "тяжелый обработчик" и без того использущий массу регистров.
"Обязательно" - это слишком категорично. Бывают проекты в которых необходимо обрабатывать очень частые прерывания, большая часть которых не требует сложных действий (а, значит и ресурсов процессора - тех же регистров). Возникает желание сэканомить на сохранении-востановлении контекста... Если "тяжелую" часть обработчика выделить в отдельную функцию и при её вызове самому позаботиться о сохранении-восстановлении регистров, то можно получить неплохой результат. Вот так это можно сделать в ICC
Код
void func(void) // Функция, вызываемая из процедуры обработки прерывания
{
...............
}

#pragma interrupt_handler proc_interrupt:x
void proc_interrupt(void) // Процедура обработки прерывания
{
  ............
  if(...)
  {
    asm("xcall push_lset"); // Вызов стандартной функции сохранения регистров
    asm("xcall _func"); // Вызов функции void func(void)
    asm("xcall pop_lset"); // Вызов стандартной функции восстановления регистров
  }
  ............
}

при этом, при входе(выходе) в(из) процедуры обработки прерывания proc_interrupt транслятор генерит код, сохраняющий(востанавливающий) необходимый минимум регистров. Если, ассемблерные вставки заменить на с-ишный вызов функции func(); , то транслятор генерит код сохраняющий(востанавливающий) все регистры.

Go to the top of the page
 
+Quote Post
zltigo
сообщение May 15 2008, 06:41
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Палыч @ May 15 2008, 08:36) *
Если...

В данном случае идет речь о чисто сишных + расширения компилятора возможностях. О ASM и его смесях, естественно, разговор был-бы другой.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 15 2008, 16:46
Сообщение #20


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(zltigo @ May 15 2008, 09:41) *
В данном случае идет речь о чисто сишных + расширения компилятора возможностях.


Вообщем, есть достаточно простой метод. Без асма, но надо проследить один момент (об этом чуть позже). Я обычно поступаю следующим образом

Код
//Флаг необходимости запуска тяжелой части
#define NeedRunPart2 GPIOR0_Bit0
//Флаг блокировки, если не нужно разрешать прерывания, можно убрать
#define Part2Lock GPIOR0_Bit1

#pragma diag_suppress=Ta006
__interrupt void Int_part1(void)
{
  //Легкая часть прерывания
  ....

  if (....) NeedRunPart2=1;
  ....
}

__interrupt void Int_part2(void)
{
  //Тут вызываем функции, извращаемся как хотим                                                                
....
....
....
}
#pragma diag_default=Ta006


#pragma vector=какой надо
__interrupt __raw void INT_dispatch(void)
{
  ((void(*)(void))Int_part1)();
  __disable_interrupt();
  if (!NeedRunPart2) return;
  if (Part2Lock) return;
  Part2Lock=1;
  NeedRunPart2=0;
  __enable_interrupt();
  ((void(*)(void))Int_part1)();
  __disable_interrupt();
  Part2Lock=0;
}


Главное тут - проверить, чтобы проверяемые и устанавливаемые флаги были в младших адресах пространства ввода-вывода, чтобы компилятор мог пользоваться SBIC/SBIS для проверки и SBI/CBI для манипуляций. Тогда можно не сохранять контекст в диспечере прерываний - эти комманды не портят SREG и другие регистры.

Вот такой код получается у диспечера:
Код
//   34 __interrupt __raw void INT_dispatch(void)
INT_dispatch:
//   35 {
//   36   ((void(*)(void))Int_part1)();
        RCALL   Int_part1
//   37   __disable_interrupt();
        CLI
//   38   if (!NeedRunPart2) return;
        SBIS    0x1E, 0x00
        RJMP    ??INT_dispatch_0
//   39   if (Part2Lock) return;
        SBIC    0x1E, 0x01
        RJMP    ??INT_dispatch_0
//   40   Part2Lock=1;
        SBI     0x1E, 0x01
//   41   NeedRunPart2=0;
        CBI     0x1E, 0x00
//   42   __enable_interrupt();
        SEI
//   43   ((void(*)(void))Int_part1)();
        RCALL   Int_part1
//   44   __disable_interrupt();
        CLI
//   45   Part2Lock=0;
        CBI     0x1E, 0x01
//   46 }
??INT_dispatch_0:
        RETI


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

И на посошок, не забыть запретить варнинг линкеру, что производится вызов обработчика прерывания как фунцкции.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.0141 секунд с 7
ELECTRONIX ©2004-2016