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

 
 
> Приоритет и вложенность прерываний, матчасть
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
2 страниц V  < 1 2  
Start new topic
Ответов (15 - 22)
maug
сообщение Jun 6 2007, 10:47
Сообщение #16


Участник
*

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



Цитата(GetSmart @ Jun 6 2007, 17:33) *
2. Вообще непонятно, какой такой исключительной ситуации?

Эта фраза из документации на SAM7 с gaw.ru пункт 12.2.3 (Режимы работы ARM7TDMI) и

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

Я имел ввиду именно это.
Go to the top of the page
 
+Quote Post
Calculator
сообщение Jun 6 2007, 10:53
Сообщение #17


Участник
*

Группа: Свой
Сообщений: 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
Сообщение #18


.
******

Группа: Участник
Сообщений: 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
Сообщение #19


Участник
*

Группа: Свой
Сообщений: 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
telerobot
сообщение Apr 10 2010, 18:49
Сообщение #20





Группа: Новичок
Сообщений: 1
Регистрация: 10-04-10
Пользователь №: 56 553



Здравствуйте.
У меня вопрос. Я работаю с AT91SAM7X. Проиннициализировал таймер и юарт. Через регистр AIC_SMR задал юарту максимальный приоритет а таймеру минимальный.
Обработчики обьявляю так: __irq __arm <название>
Я все это сделал но вложенные прерывания не срабатывают. При попадании в обработчик таймера и наступлении прерывания от юарта, в обработчик юарта я попадаю только после завершения обработчика таймера.
У меня вопрос, что нужно сделать, что бы заработали вложенные прерывания?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Apr 10 2010, 23:47
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Посмотреть свежий топик http://electronix.ru/forum/index.php?showtopic=74904&hl=.

Про прерывания в ARM уж на форуме все разжевали и в рот положили. Ан нет, туда же. Что поискать в тягость?
Go to the top of the page
 
+Quote Post
malysh_nrg
сообщение Apr 12 2010, 11:36
Сообщение #22





Группа: Участник
Сообщений: 8
Регистрация: 19-06-07
Пользователь №: 28 558



Цитата(telerobot @ Apr 10 2010, 23:04) *
что нужно сделать, что бы заработали вложенные прерывания?


Бесспорно, их нужно разрешить. Разрешить на уровне ядра и на уровне периферии. Внимательно изучите ассемблеровский код в СтартАпе в части настройки режимов и в части обработки прерывания. В моём примере стартАп-а (ссылка в посте выше), на первый и беглый взгляд, в прерывания IRQ (где у меня запрещены прерывания, метка IRQ_Handler_Entry: ) перед самым скачком в п/п-обработчик периферии ядро переключается в основной режим SYS, где (!была моя проблема) уже разрешены прерывания.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Apr 12 2010, 15:20
Сообщение #23


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(telerobot @ Apr 10 2010, 23:04) *
Обработчики обьявляю так: __irq __arm <название>


Аттрибуты функции __irq __arm предназначены для невложенных прерываний.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 08:11
Рейтинг@Mail.ru


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