|
|
  |
Прерывания в AT91SAM7X. Не входит в обработчик. |
|
|
|
Jan 30 2013, 11:15
|
Группа: Новичок
Сообщений: 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] - для короткого!!!
|
|
|
|
|
Jan 30 2013, 11:20
|
Знающий
   
Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840

|
Цитата(talos85 @ Jan 30 2013, 14:15)  Но обработчик прерывания не вызывается Покажите startup.s Глобально прерывания в ядре разрешены? Что в CPSR?
|
|
|
|
|
Jan 30 2013, 11:24
|
Группа: Новичок
Сообщений: 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
|
|
|
|
|
Jan 30 2013, 13:20
|
Группа: Новичок
Сообщений: 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] - для короткого!!!
|
|
|
|
|
Jan 30 2013, 13:46
|

Местный
  
Группа: Свой
Сообщений: 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
Причина редактирования: избыточное цитирование
|
|
|
|
|
Jan 30 2013, 13:51
|
Группа: Новичок
Сообщений: 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++"? Вроде флаг события должен сбросится при этом... К сожалению не помогло
|
|
|
|
|
Jan 30 2013, 14:01
|

Местный
  
Группа: Свой
Сообщений: 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
последняя команда Вас не касается
|
|
|
|
|
Jan 30 2013, 14:21
|
Группа: Новичок
Сообщений: 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; И все работает  ))) Благодарю!!! Но все-таки странно, по даташиту прерывание должно само сбрасываться. Возможно, я что-то не так понял. Все правильно  Разобрался. Сбрасывать прерывание записью в регистр ICCR в обработчике не надо. А вот читать TC_SR обязательно. To RabidRabbit: ваша подсказка была полностью верной. Я видимо когда пробовал первый раз, прочитал статус-регистр от другого таймера. Благодарю всех участников темы  )) Всем успехов!
Сообщение отредактировал IgorKossak - Jan 30 2013, 15:45
Причина редактирования: бездумное цитирование, пробельные строки
|
|
|
|
|
Jan 30 2013, 16:17
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 31 2013, 19:33
|
Группа: Новичок
Сообщений: 6
Регистрация: 25-02-07
Из: Москва
Пользователь №: 25 663

|
Точно так и есть. В разных версиях IAR встречались разные стандартные стартапы. Соответственно работают как описано выше.
Сообщение отредактировал IgorKossak - Jan 31 2013, 20:06
Причина редактирования: бездумное цитирование
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|