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

 
 
 
Reply to this topicStart new topic
> Прерывания в AT91SAM7X. Не входит в обработчик.
talos85
сообщение Jan 30 2013, 11:15
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 30-01-13
Пользователь №: 75 404



Добрый день.
Коллеги, прошу помощи, всю голову уже сломал.
Необходимо прерывание по таймеру. Инициализирую AIC, инициализирую и запускаю таймер. Таймер считает. Но обработчик прерывания не вызывается, не смотря на то, что я в IARe вижу, что в AIC_IPR (pending register) выставляется соответствующий бит.

Кусок программы:
CODE
volatile uDWORD temp = 0;

void Timer0_Handler()
{
temp++;
AT91C_BASE_AIC -> AIC_EOICR = 1;
}

void main()
{
AT91C_BASE_PMC -> PMC_PCER = (1 << AT91C_ID_TC0);
AT91C_BASE_AIC -> AIC_SMR[AT91C_ID_TC0] =
(0x00 << 5) | // Level sensitive
(0x07 << 0); // Prior
AT91C_BASE_AIC -> AIC_SVR[AT91C_ID_TC0] = (unsigned int) Timer0_Handler;
AT91C_BASE_AIC -> AIC_ICCR = (0x1 << AT91C_ID_TC0);
AT91C_BASE_AIC -> AIC_IECR = (0x1 << AT91C_ID_TC0);

AT91C_BASE_TC0 -> TC_CMR =
(0x1 << 0) |
(0x2 << 13) |
(0x1 << 15);

AT91C_BASE_TC0 -> TC_RC = 60000;
AT91C_BASE_TC0 -> TC_CCR = (0x1 << 0) | (0x1 << 2);
AT91C_BASE_TC0 -> TC_IER = (1 << 4);
while (1);
}

Пробовал также сделать прерывание на ногу контроллера. Тот же результат. Бит в AIC Pendidng-регистре выставляется, а в обработчик программа не входит.

В чем может быть дело? Что я упустил?

Заранее благодарен.

Сообщение отредактировал IgorKossak - Jan 30 2013, 13:48
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Jan 30 2013, 11:20
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(talos85 @ Jan 30 2013, 14:15) *
Но обработчик прерывания не вызывается

Покажите startup.s
Глобально прерывания в ядре разрешены? Что в CPSR?
Go to the top of the page
 
+Quote Post
talos85
сообщение Jan 30 2013, 11:24
Сообщение #3





Группа: Новичок
Сообщений: 5
Регистрация: 30-01-13
Пользователь №: 75 404



Цитата(DmitryM @ Jan 30 2013, 15:20) *
Покажите startup.s
Глобально прерывания в ядре разрешены? Что в CPSR?


А можно поподробнее про CPSR?
Файл прикрепил.Прикрепленный файл  Cstartup.zip ( 3.48 килобайт ) Кол-во скачиваний: 68

Значения в CPSR:
N = 0
Z = 1
C = 1
V = 0
Q = 0
I = 1
F = 1
T = 0
MODE = 0b11111


Сообщение отредактировал talos85 - Jan 30 2013, 11:29
Go to the top of the page
 
+Quote Post
SII
сообщение Jan 30 2013, 13:08
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Прерывания запрещены -- I = 1.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jan 30 2013, 13:11
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Цитата(talos85 @ Jan 30 2013, 15:24) *
А можно поподробнее про CPSR?

http://www.gaw.ru/html.cgi/txt/doc/micros/...rigist_spsr.htm

Цитата(talos85 @ Jan 30 2013, 15:24) *
Значения в CPSR:
I = 1
F = 1

Вопрос в раздел для начинающих? sm.gif
Go to the top of the page
 
+Quote Post
talos85
сообщение Jan 30 2013, 13:20
Сообщение #6





Группа: Новичок
Сообщений: 5
Регистрация: 30-01-13
Пользователь №: 75 404



Огромное всем спасибо за быстрые ответы.
Добавил __enable_interrupt();, (кстати очень не люблю такие средоориентированные инструкции) и в прерывание начал заходить, соответственно флажки в CPSR правильные! Ура!

Теперь другая проблема: он не сбрасывает прерывание после обработки. Т.е. выйдя из обработчика снова туда заходит со всеми вытекающими в виде переполнения стека....

Вопрос: почему не происходит очистки прерывания?

Код обработчика:
Код
void Timer1_Handler()
{
  temp++;
  AT91C_BASE_AIC -> AIC_EOICR = 1;
}


Сообщение отредактировал IgorKossak - Jan 30 2013, 13:49
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 30 2013, 13:42
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (talos85 @ Jan 30 2013, 15:20) *
Код обработчика:
А как организовано ветвление по обработчикам, т.е. чтение регистра вектора из AIC?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jan 30 2013, 13:46
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Цитата(talos85 @ Jan 30 2013, 17:20) *
void Timer1_Handler()
{
temp++;
AT91C_BASE_AIC -> AIC_EOICR = 1;
}

А если добавить чтение регистра TC_SR после "temp++"? Вроде флаг события должен сбросится при этом...

Сообщение отредактировал IgorKossak - Jan 30 2013, 13:50
Причина редактирования: избыточное цитирование
Go to the top of the page
 
+Quote Post
talos85
сообщение Jan 30 2013, 13:51
Сообщение #9





Группа: Новичок
Сообщений: 5
Регистрация: 30-01-13
Пользователь №: 75 404



Цитата(Сергей Борщ @ Jan 30 2013, 17:42) *
А как организовано ветвление по обработчикам, т.е. чтение регистра вектора из AIC?


Так все, как я понимаю, должно автоматом происходить. При настройке AIC (в первом посте листинг) я задаю адрес обработчика, соответствующего конкретно прерыванию от Таймера0. И разрешаю это прерывание.
В обработчике я не читаю регистров. А только пишу в EOICR последней инструкцией, говоря AIC, что обработка закончена.
Пробовал в обработчике принудительно очищать прерывание (хотя по мануалу это бессмысленно), но результат тот же.


Цитата(RabidRabbit @ Jan 30 2013, 17:46) *
А если добавить чтение регистра TC_SR после "temp++"? Вроде флаг события должен сбросится при этом...


К сожалению не помогло sad.gif
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jan 30 2013, 14:01
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



реальный рабочий код выхода из прерывания, только тут TC2
CODE

; read state register for tracking timer
ldr r12, [r10, #TC2_SR]
; очистка состояния прерывания
ldr r12, =(1 << 14)
str r12, [r11, #AIC_ICCR]
; сообщим AIC, что прерывание всё
str r12, [r11, #AIC_EOICR]
; return from interrupt
subs PC, LR, #4

последняя команда Вас не касается sm.gif
Go to the top of the page
 
+Quote Post
talos85
сообщение Jan 30 2013, 14:21
Сообщение #11





Группа: Новичок
Сообщений: 5
Регистрация: 30-01-13
Пользователь №: 75 404



Добавил в обработчик то же, но на Си:

temp = AT91C_BASE_TC1 -> TC_SR;
AT91C_BASE_AIC -> AIC_ICCR = 0x1 << AT91C_ID_TC0;
AT91C_BASE_AIC -> AIC_EOICR = 1;

И все работает sm.gif)))
Благодарю!!!
Но все-таки странно, по даташиту прерывание должно само сбрасываться. Возможно, я что-то не так понял.
Все правильно sm.gif Разобрался. Сбрасывать прерывание записью в регистр ICCR в обработчике не надо. А вот читать TC_SR обязательно.
To RabidRabbit: ваша подсказка была полностью верной. Я видимо когда пробовал первый раз, прочитал статус-регистр от другого таймера.
Благодарю всех участников темы sm.gif)) Всем успехов!

Сообщение отредактировал IgorKossak - Jan 30 2013, 15:45
Причина редактирования: бездумное цитирование, пробельные строки
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 30 2013, 16:17
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (talos85 @ Jan 30 2013, 15:51) *
Так все, как я понимаю, должно автоматом происходить.
Автоматом происходит переход на вектор исключения по адресу 0x000018. По этому адресу находится ваш или библиотечный обработчик исключеия, который читает из регистра IVR адрес конкретного обработчика прерывания и передает ему управление. Этот обработчик исключения может быть реализован двумя способами:
1) Читает регистр и передает управление вашему обработчику одной командой.
2) Организовывает пролог обработчика, читает регистр и вызывает ваш обработчик как обычную функцию, по возвращению из нее выполняет эпилог и возврат из исключения.

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Doux
сообщение Jan 31 2013, 19:33
Сообщение #13





Группа: Новичок
Сообщений: 6
Регистрация: 25-02-07
Из: Москва
Пользователь №: 25 663



Точно так и есть. В разных версиях IAR встречались разные стандартные стартапы. Соответственно работают как описано выше.

Сообщение отредактировал IgorKossak - Jan 31 2013, 20:06
Причина редактирования: бездумное цитирование
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 13th August 2025 - 11:57
Рейтинг@Mail.ru


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