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

 
 
> Приоритет и вложенность прерываний, матчасть
maug
сообщение Jun 5 2007, 03:16
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 18
Регистрация: 12-04-07
Пользователь №: 26 989



На сколько я понял, в SAM7 уровень прерываний заложен, но чтобы он правильно работал, необходимо написать правильный обработчик прерывания. Или я не прав? В простейшем случае необходимо в начале и в конце обработчика поставить define библиотеки ...:
__ENABLE_INTERRUPT();
__DISABLE_INTERRUPT();

Провел несколько простых экспериментов, с использованием таймеров 0 и 1
Код
#define TIMER0_INTERRUPT_LEVEL      0
#define TIMER1_INTERRUPT_LEVEL      1

#pragma interrupt_handler Timer0_CIrqHandler
void Timer0_CIrqHandler(void)
{
  unsigned int  status,r0;
__ENABLE_INTERRUPT();
status = TC0_SR;              // Read timer status register to clear interrupt
   PIO_CODR = (1<<0);        // LED1 ON
   for(r0=0; r0<0x5FFF; r0++);
   PIO_SODR = (1<<0);        //  LED1 OFF
  AIC_EOICR = status;            
__DISABLE_INTERRUPT();
}

#pragma interrupt_handler Timer1_CIrqHandler
void Timer1_CIrqHandler(void)
{
  unsigned int  status,r1;
__ENABLE_INTERRUPT();
   status = TC1_SR;              // Read timer status register to clear interrupt
       PIO_CODR = (1<<1);        // LED2 ON
      for(r1=0; r1<0x4FF; r1++);
       PIO_SODR = (1<<1);        //  LED2 OFF
  AIC_EOICR = status;        
__DISABLE_INTERRUPT();
}


void timer0_init ( void )
{
  PMC_PCER = (0x1 << AT91C_ID_TC0);      
  TC0_CCR = AT91C_TC_CLKDIS;          
  TC0_IDR = 0xFFFFFFFF;  
                                        
  AIC_SVR12 = (unsigned int) Timer0_CIrqHandler;
  AIC_SMR12 =AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE|TIMER0_INTERRUPT_LEVEL;  

  AIC_IECR = (0x1 << AT91C_ID_TC0);

  TC0_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_CPCTRG;
  TC0_RC = 0x0FF0;                   
  TC0_IER = AT91C_TC_CPCS;
  
  TC0_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}

void timer1_init ( void )
{
  PMC_PCER = (0x1 << AT91C_ID_TC1);    

  TC1_CCR = AT91C_TC_CLKDIS;
  TC1_IDR = 0xFFFFFFFF;
  
                                        
  AIC_SVR13 = (unsigned int) Timer1_CIrqHandler;
  AIC_SMR13 =AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE|TIMER1_INTERRUPT_LEVEL;

  AIC_IECR = (0x1 << AT91C_ID_TC1);

  TC1_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_CPCTRG;
  TC1_RC = 0x00FF;
  TC1_IER = AT91C_TC_CPCS;
  
  TC1_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}


после использования __ENABLE_INTERRUPT(); __DISABLE_INTERRUPT();
действительно уровень прерывания стал работать как надо.
Но вот попробовал подключить ШИМ:
Код
#define F_PWC 0xFF
#define PWMC_INTERRUPT_LEVEL 5  

#pragma interrupt_handler PWMC_CIrqHandler
void PWMC_CIrqHandler(void)
{
  unsigned int  status,rir,ss;

  __ENABLE_INTERRUPT();
  status = PWM_ISR;
  AIC_ICCR = (0x1 << AT91C_ID_PWMC);  
  
  PWM_CMR0 = (0<<10)|0x03;
  PWM_CUPD0 = F_PWC/3;
  AIC_EOICR = status;
   __DISABLE_INTERRUPT();
}


void init_pwm(){
int i;
     *AT91C_PIOA_PDR = (1<<23);  // подключаем выв PA23 к шиму
     *AT91C_PIOA_BSR = (1<<23);          

     PMC_PCER = (1<<AT91C_ID_PWMC);
        
     AIC_SMR10 = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | PWMC_INTERRUPT_LEVEL;
        
     AIC_SVR10 = (unsigned int) PWMC_CIrqHandler;
     AIC_IECR = (1 << AT91C_ID_PWMC);
    
    // PWM_MR =(0x00<<24)|(0x01<<16)|(0x00<<8) |(0x01<<0);
     PWM_CMR0 = (0<<10)| (0<<9)| (0<<8) | 0x03;
     PWM_CPRD0 = F_PWC;
     PWM_CDTY0 = F_PWC/10;
     PWM_IER = AT91C_PWMC_CHID0;
     PWM_ENA = AT91C_PWMC_CHID0;
     }
    
}


В таком виде программа виснет, как только срабатывает прерывание ШИМа, точнее когда оно выходит из него.
Пробовал убрать __ENABLE_INTERRUPT(); __DISABLE_INTERRUPT(); из всех прерываний все работает, только без преоритетов. По отдельности так же все работает. В чем дело не пойму. Может необходимо более полный обработчик написать? помогите!
Пишу на ICCARM для AT91SAM7S256. Startup стандартный crtat91sam7s.s

Сообщение отредактировал maug - Jun 5 2007, 03:20
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
GetSmart
сообщение Jun 6 2007, 05:37
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
На сколько я понял с таким обработчиком, все команды (функции) тела прерывания будут использовать не IRQ стек, а общий стек лимитированный лишь размером памяти?

Всё верно.
Код
ldr R14, =AT91C_BASE_AIC;Считать вектор в R0
ldr R0 , [R14, #AIC_IVR]
ldr R14, =AT91C_BASE_AIC;Отметить окончание прерывания в
str R14, [R14, #AIC_EOICR]
Тут скорее всего косяк. Сбрасывать признак прерывания нужно в самом конце прерывания, а не сразу на входе. И общие прерывания уже должны быть запрещены. Вобщем алгоритм такой:
1. Прочитать вектор возникшего прерывания.
2. Перейти на обработчик
3. Сохранить адрес возврата (LR) и переключиться в SYS Mode
4. Разрешить общие прерывания
5. Обработать процедуру прерывания
6. Запретить общие прерывания
7. Переключиться обратно в IRQ Mode и восстановить LR
8. Сбросить флаг прерывания в AIC (AIC_EOICR)
9. Выйти из прерывания

7 и 8 можно поменять.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Calculator
сообщение Jun 6 2007, 10:53
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 45
Регистрация: 19-04-07
Пользователь №: 27 172



Цитата(GetSmart @ Jun 6 2007, 11:37) *
Код
ldr R14, =AT91C_BASE_AIC;Отметить окончание прерывания в
str R14, [R14, #AIC_EOICR]
Тут скорее всего косяк. Сбрасывать признак прерывания нужно в самом конце прерывания, а не сразу на входе. И общие прерывания уже должны быть запрещены.

Здесь нет косяка smile.gif
Общие прерывания запрещены строчкой выше (вот этой)
Код
msr     CPSR_c, #I_BIT | ARM_MODE_IRQ;Запретить прерывания и переключиться назад в IRQ mode

Запись в AT91C_BASE_AIC разрешает контроллеру прерываний SAM7 выставить новый запрос прерывания ядру. Ядро запустит обработчик только после выполнения последней команды обработчика, которая сделает возврат и переключит режим ядра из IRQ в USER/SUPERVISOR.
Этот обработчик нормально работает в нескольких проектах с активным использованием прерываний
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 6 2007, 11:14
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Calculator @ Jun 6 2007, 16:53) *
Здесь нет косяка smile.gif
Общие прерывания запрещены строчкой выше (вот этой)
Код
msr     CPSR_c, #I_BIT | ARM_MODE_IRQ;Запретить прерывания и переключиться назад в IRQ mode

Запись в AT91C_BASE_AIC разрешает контроллеру прерываний SAM7 выставить новый запрос прерывания ядру. Ядро запустит обработчик только после выполнения последней команды обработчика, которая сделает возврат и переключит режим ядра из IRQ в USER/SUPERVISOR.
Этот обработчик нормально работает в нескольких проектах с активным использованием прерываний

Запись -----//----- разрешает контроллеру прерываний реагировать (сразу исполнять, если разрешены общие прерывания) на прерывания с более низким приоритетом чем текущий. В прерываниях, в которых разрешены вложенные прерывания эту команду ставят в самом конце прерывания перед самым выходом, по вполне очевидным причинам.

Запоминает же контроллер все прерывания, вне зависимости от их приоритета и записи в AT91C_BASE_AIC, что бы потом, после выхода из текущего прерывания (или даже внутри него) обработать все запомненные прерывания в порядке приоритета и пожеланий программиста.

Цитата(maug @ Jun 6 2007, 16:47) *
Эта фраза из документации на SAM7 с gaw.ru пункт 12.2.3 (Режимы работы ARM7TDMI) и

12.2.4.3 Типы исключительных ситуаций
Ядро поддерживает пять типов исключительных ситуаций, работающих в привилегированном режиме. Ниже приведен их список:
1 быстрое прерывание (FIQ)
2 обычное прерывание (IRQ)
3 аварийная ситуация при работе с памятью (используется для реализации защищенного режима работы памяти или виртуальной памяти)
4 сбой при выполнении команды или выполнение несуществующей команды
5 программные прерывания (SWI)

Я имел ввиду именно это.

При возникновении исключительной ситуации используется персональный стек этого исключения.

Прочитайте что ли файлик arm7tdmi.pdf
А то придётся всё содержимое этого файла вам разжёвывать.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Calculator
сообщение Jun 8 2007, 06:22
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 45
Регистрация: 19-04-07
Пользователь №: 27 172



Цитата(GetSmart @ Jun 6 2007, 17:14) *
Запись -----//----- разрешает контроллеру прерываний реагировать (сразу исполнять, если разрешены общие прерывания) на прерывания с более низким приоритетом чем текущий. В прерываниях, в которых разрешены вложенные прерывания эту команду ставят в самом конце прерывания перед самым выходом, по вполне очевидным причинам.

Могу повторить только то, что уже писал. Запись -----//----- действительно разрешает контроллеру прерываний реагировать, но не исполнять, т.к. сброшен флаг разрешения прерываний IRQ в регистре статуса. Последняя команда обработчика прерывания переключает режим ядра, делает возврат в фоновую програму и разрешает прерывания IRQ. Если они есть, то самое приоритетное из них будет выполнено после выполнения одной инструкции из фоновой программы

Цитата(maug @ Jun 5 2007, 17:45)
Этот код видел вот только из за особенности ICCARM асемблера не могу прикрутить аналогичную. не понимает команды работы
ldr R14, =AT91C_BASE_AIC ;Считать вектор в R0
ldr R0 , [R14, #AIC_IVR]
ldr R14, =AT91C_BASE_AIC ;Отметить окончание прерывания в
str R14, [R14, #AIC_EOICR]

Может у кого нибудь есть опыт работы ICC?

На сколько я понял с таким обработчиком, все команды (функции) тела прерывания будут использовать не IRQ стек, а общий стек лимитированный лишь размером памяти?

Опыта работы с ICC у меня нет, но нужно просто разобраться, почему не понимаются эти команды. Может быть у ассемблера немного отличается синтаксис, может быть нет define на AT91C_BASE_AIC, может быть define есть, но равен не тому же, чему в IAR. На всякий случай вот эти define:
Код
AT91C_BASE_AIC  EQU       0xFFFFF000 ;Базовый адрес контроллера прерываний
AIC_IVR         EQU       0x100;Регистр вектора IRQ (смещение)
AIC_FVR         EQU       0x104;Регистр вектора FIQ
AIC_EOICR     EQU       0x130;Регистр "Окончание прерывания"

Стек режима IRQ использоваться будет, но мало и его максимальная длина фиксирована. Для максимум 8 вложенных прерываний (а больше не разрешит контроллер прерываний) длина стека IRQ должна быть 3*4*8 байт (3 двойных слова на 8 уровней приоритетов). Если используется всего пара приоритетов, то соответственно 3*4*2

Сообщение отредактировал Calculator - Jun 8 2007, 06:27
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- maug   Приоритет и вложенность прерываний   Jun 5 2007, 03:16
- - Calculator   Может размер стека режима прерываний мал? В станда...   Jun 5 2007, 05:46
- - GetSmart   Есть такая штука как вложенные прерывания. Так вот...   Jun 5 2007, 06:30
|- - maug   ЦитатаМожет размер стека режима прерываний мал? В ...   Jun 5 2007, 06:46
|- - Calculator   Цитата(GetSmart @ Jun 5 2007, 12:30) Кста...   Jun 5 2007, 10:49
- - maug   Нашел вставки в прерывания аналог слово __nested. ...   Jun 5 2007, 07:59
- - GetSmart   Похоже на правду. А в каком компиляторе пишите на...   Jun 5 2007, 10:45
- - GetSmart   Цитата(Calculator)В SAM7 можно, его контроллер пре...   Jun 5 2007, 11:26
- - maug   Цитата(GetSmart @ Jun 5 2007, 17:45) А в ...   Jun 6 2007, 02:45
|- - zltigo   Цитата(maug @ Jun 6 2007, 05:45) На сколь...   Jun 6 2007, 07:02
- - GetSmart   zltigo, не мутите воду. Запутаете всех окончательн...   Jun 6 2007, 07:07
|- - zltigo   Цитата(GetSmart @ Jun 6 2007, 10:07) Запу...   Jun 6 2007, 08:11
|- - maug   Эту тему я открыл, чтобы разобраться окончательно ...   Jun 6 2007, 09:49
- - GetSmart   1. System обычно. Иногда User. 2. Вообще непонятно...   Jun 6 2007, 10:33
|- - maug   Цитата(GetSmart @ Jun 6 2007, 17:33) 2. В...   Jun 6 2007, 10:47
- - telerobot   Здравствуйте. У меня вопрос. Я работаю с AT91SAM7X...   Apr 10 2010, 18:49
|- - malysh_nrg   Цитата(telerobot @ Apr 10 2010, 23:04) чт...   Apr 12 2010, 11:36
|- - sergeeff   Цитата(telerobot @ Apr 10 2010, 23:04) Об...   Apr 12 2010, 15:20
- - sergeeff   Посмотреть свежий топик http://electronix.ru/forum...   Apr 10 2010, 23:47


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

 


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


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