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

 
 
> Приоритет и вложенность прерываний, матчасть
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
Ответов (1 - 22)
Calculator
сообщение Jun 5 2007, 05:46
Сообщение #2


Участник
*

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



Может размер стека режима прерываний мал? В стандартных стартап-файлах и в примерах на это внимание не обращают.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 5 2007, 06:30
Сообщение #3


.
******

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



Есть такая штука как вложенные прерывания. Так вот. Чтобы их разрешить в АРМе нужно кое-что особенное. Вобщем пролог и эпилог таких прерываний отличается от обычных. Кстати, в обычных прерываниях нельзя разрешать прерывания. По крац\йней мере в ИАРе так. Для вложенных прерываний существует слово __nested. К примеру так описывается заголвок прерывания:
__irq __arm __nested Timer0Interrupt()


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


Участник
*

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



Цитата
Может размер стека режима прерываний мал? В стандартных стартап-файлах и в примерах на это внимание не обращают

Размер стека IRQ сделал 1000 вроде для такой программы это с N кратным запасом

Цитата
Есть такая штука как вложенные прерывания. Так вот. Чтобы их разрешить в АРМе нужно кое-что особенное. Вобщем пролог и эпилог таких прерываний отличается от обычных. Кстати, в обычных прерываниях нельзя разрешать прерывания. По крац\йней мере в ИАРе так. Для вложенных прерываний существует слово __nested. К примеру так описывается заголвок прерывания:
__irq __arm __nested Timer0Interrupt()

Я примерно об этом и имел ввиду, говоря об специальном обработчике прерывания. Примерно то и суть действий ясна, да вот только примерно. Может кто знает как правильно написать обработчик прерывания или хотябы где посмотреть?
Go to the top of the page
 
+Quote Post
maug
сообщение Jun 5 2007, 07:59
Сообщение #5


Участник
*

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



Нашел вставки в прерывания аналог слово __nested.
#define IENABLE /* Nested Interrupts Entry */
asm(" MRS LR, SPSR"); /* Copy SPSR_irq to LR */
asm (" STMFD SP!, {LR}"); /* Save SPSR_irq */
asm (" MSR CPSR_c, #0x1F"); /* Enable IRQ (Sys Mode)

#define IDISABLE /* Nested Interrupts Exit */
asm (" LDMFD SP!, {LR}"); /* Restore LR */
asm (" MSR CPSR_c, #0x92"); /* Disable IRQ (IRQ Mode) */
asm (" LDMFD SP!, {LR}"); /* Restore SPSR_irq to LR */
asm (" MSR SPSR_cxsf, LR"); /* Copy LR to SPSR_irq */

Вроде все стало работать.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 5 2007, 10:45
Сообщение #6


.
******

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



Похоже на правду.

А в каком компиляторе пишите на си?


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


Участник
*

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



Цитата(GetSmart @ Jun 5 2007, 12:30) *
Кстати, в обычных прерываниях нельзя разрешать прерывания. По крайней мере в ИАРе так

В SAM7 можно, его контроллер прерываний обеспечивает при разрешенных прерываниях обработку только более приоритетных прерываний, чем выполняемое в данный момент. Правда есть нюанс, связанный с армовской архитектурой. Прерывание переключает режим ядра в IRQ. Для того, чтобы не испортить адрес возврата и флаги, сначала нужно сохранить их в стеке IRQ, а затем переключиться в режим USER или SUPERVISOR, и только после этого разрешить прерывания.
Обработчик IRQ из IAR'овского cstartup для SAM7 отличается от обработчиков для других ARMов.
Код
IRQ_Handler_Entry:
        sub     LR, LR, #4               ;Сохранение LR_irq в стеке IRQ
        stmfd   SP!, {LR}
        mrs     R14, SPSR                ;Сохранить SPSR в стеке для вложенных прерываний
        stmfd   SP!, {R14}
        stmfd   SP!, {R0}                ;Сохранение R0 в стеке IRQ

        ldr     R14, =AT91C_BASE_AIC     ;Считать вектор в R0
        ldr     R0 , [R14, #AIC_IVR]
        msr     CPSR_c, #ARM_MODE_SVC    ;Разрешить прерывания и переключиться в Supervisor Mode
        stmfd   SP!, {R1-R3, R12, R14}   ;Сохранить используемые регистры в User-стеке

        mov     LR, PC                   ;Выполнить процедуру прерывания по вектору из AIC_IVR
        bx      R0

        ldmia   SP!, { R1-R3, R12, R14}  ;Восстановить используемые регистры из User-стека
        msr     CPSR_c, #I_BIT | ARM_MODE_IRQ;Запретить прерывания и переключиться назад в IRQ mode

        ldr     R14, =AT91C_BASE_AIC     ;Отметить окончание прерывания в регистре AIC_EOICR
        str     R14, [R14, #AIC_EOICR]

        ldmia   SP!, {R0}                ;Восстановление SPSR_irq и R0 из стека IRQ
        ldmia   SP!, {R14}
        msr     SPSR_cxsf, R14
        ldmia   SP!, {PC}^               ;Восстановление скорректированного LR_irq из IRQ-стека прямо в PC

Сишные обработчики при этом оформляются не только без слова __nested, но и без interrupt_handler, то есть как обычные процедуры.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 5 2007, 11:26
Сообщение #8


.
******

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



Цитата(Calculator)
В SAM7 можно, его контроллер прерываний обеспечивает при разрешенных прерываниях обработку только более приоритетных прерываний, чем выполняемое в данный момент.

NO WAY !!!
А где не так??? В LPC тоже контроллер прерываний не настолько тупой.
Цитата
Правда есть нюанс, связанный с армовской архитектурой. Прерывание переключает режим ядра в IRQ.
Именно его я и имел ввиду, что дальнейшие мои слова и подтверждают. И именно для этого придумано слово __nested.

__nested и для SAM7 подойдёт, если прога для ИАРа

Цитата(Calculator)
В SAM7 можно
Попробуйте объявить простой обработчик прерываний (невложенных) и разрешить в нём прерывания. Проверьте. А потом пишите...


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


Участник
*

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



Цитата(GetSmart @ Jun 5 2007, 17:45) *
А в каком компиляторе пишите на си?

Пишу на ICCARM 7

Цитата(Calculator @ Jun 5 2007, 17:49) *
Обработчик IRQ из IAR'овского cstartup для SAM7 отличается от обработчиков для других ARMов.


Этот код видел вот только из за особенности ICCARM асемблера не могу прикрутить аналогичную. не понимает команды работы
ldr R14, =AT91C_BASE_AIC ;Считать вектор в R0
ldr R0 , [R14, #AIC_IVR]
ldr R14, =AT91C_BASE_AIC ;Отметить окончание прерывания в
str R14, [R14, #AIC_EOICR]

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

На сколько я понял с таким обработчиком, все команды (функции) тела прерывания будут использовать не IRQ стек, а общий стек лимитированный лишь размером памяти?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 6 2007, 05:37
Сообщение #10


.
******

Группа: Участник
Сообщений: 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
zltigo
сообщение Jun 6 2007, 07:02
Сообщение #11


Гуру
******

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



Цитата(maug @ Jun 6 2007, 05:45) *
На сколько я понял с таким обработчиком, все команды (функции) тела прерывания будут использовать не IRQ стек,

С чего-бы это вдруг? Mode не меняли, указатель стека тоже.
Цитата
а общий стек лимитированный лишь размером памяти?

Понятия "общего стека" вообще нет. Есть конкретные стеки для режимов. Под стеки память по любому выделяется идивидуально программистом. Один (любой) из стеков неизвестного (типа сколько останется (а не вообще сколько есть!) памяти, столько и будет) размера можно конечно сделать, но это верный путь к проблемам.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 6 2007, 07:07
Сообщение #12


.
******

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



zltigo, не мутите воду. Запутаете всех окончательно. Или почитайте внимательно всё с начала.

PS Общий стек = стек основной программы.


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


Гуру
******

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



Цитата(GetSmart @ Jun 6 2007, 10:07) *
Запутаете всех окончательно. Или почитайте внимательно всё с начала.

Если имеется конкретный кусок кода и нему конкретный вопрос ответ на который не меет отношения к этому коду, то это означает только одно - все уже запутались окончательно и без меня smile.gif
Цитата
PS Общий стек = стек основной программы.

Ну а что тогда "основная программа" - прерванная? - понимаю. Но ведь разборок с тем, из какого режима вывалились в IRQ Mode я не вижу, есть бездумная установка Supervisor Mode вне зависимости от того, какй прервали. Но основная причина моего коммента была в том, что мене не понравилось некое Ваше с maug совместное утверждение "прерывания будут использовать не IRQ стек, а общий стек лимитированный лишь размером памяти?" не только по причине мутного "общего стека", но в основном по причине того, что он "лимитированный лишь размером памяти".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
maug
сообщение Jun 6 2007, 09:49
Сообщение #14


Участник
*

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



Эту тему я открыл, чтобы разобраться окончательно в прерываниях их приоритетах, вложениях, отсюда стеках...

Может тема уже стала несколько запутанной, может быть я совсем недавно програмирую под АРМ.
Чтобы разобраться прошу поправить если я что, то не так понимаю.

1 Основная программа и ее подпрограммы используют супервизорный стек.
2 При возникновении исключительной ситуации в нашем случае прерывание используется стек IRQ
3 Если тело обработчика использует функции то опять же используется IRQ стек (по умолчанию)
4 Для обработчика ...IRQ_Handler_Entry:... из IAR получается,что из IRQ стека используются только 4 байта (1 указатель), а далее стек переопределяется и используется супервизорный стек. Обработчик прерывания по сути представляется как обычная функция.

Приведенный в самом начале код, это лишь наглядный (осцил) эксперимент, для изучения прерываний.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 6 2007, 10:33
Сообщение #15


.
******

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



1. System обычно. Иногда User.
2. Вообще непонятно, какой такой исключительной ситуации?
3. System/User
4. Как минимум 4 байта стека IRQ, потом переключение на стек System/User


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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