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

 
 
 
Reply to this topicStart new topic
> Обработка прерывания от SPI, at91sam7s256
Bulat
сообщение Mar 30 2007, 09:53
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



1. Какому источнику прерывания в регистре AIC_IECR (PID2, 3, 4,...) соответствует прерывание от SPI?
2. Вектор прерывания ARM находится по адресу 0х18. Можно по этому адресу записать команду, типа goto "метка", а метку уже поставить рядом с функцией обработки прерывания, ну и таким образом вызвать функцию обработки прерывания? Ну даже если делать как написано в документации, т.е. производить чтение AIC_IVR, то как именно по адресу 0х18 записать нужную команду. Я понимаю так:

adr[int()]=0x18; //задаем адрес ф-ии int()
void int()
{
goto 1;
}
1: void irq() //функция обрабоки прерывания
{
...
}

Только оператор adr[] IAR не воспринимает.
3. Как по другому задать адрес функции?
Если можно то напишите свой вариант кода на С.
Заранее благодарен!
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Mar 30 2007, 10:22
Сообщение #2


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



1 гыгы
В даташите от атмела есть загадочные места. smile.gif На самом деле узнать ID можно глянув на включаемый файл.
#define AT91C_ID_SPI ((unsigned int) 5) // Serial Peripheral Interface

2.
Нифига не понял. если Вы про то как сконфигурировать AIC то
функция AT91F_AIC_ConfigureIt из файла lib_at91sam7s256.h Вам поможет

3. Что означает вопрос не понял. Получить адрес функции в С просто - это ее имя.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 30 2007, 12:39
Сообщение #3


Гуру
******

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



Цитата(Bulat @ Mar 30 2007, 08:53) *
Если можно то напишите свой вариант кода на С.
Вот тут посмотрите. Как раз описывал несколько возможных вариантов.


--------------------
На любой вопрос даю любой ответ
"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
Bulat
сообщение Apr 6 2007, 07:47
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(Сергей Борщ @ Mar 30 2007, 14:39) *
Вот тут посмотрите. Как раз описывал несколько возможных вариантов.

Спасибо за ссылку!
Посмотрев подход №2 у меня возникло несколько вопросов.

Цитата
2) Делается одна функция-обработчик в которой делается сохранение/восстановление регистров и из этой функции вызываются обработчики, которые представляют из себя обычные функции. Функция-обработчик "подвешивается" на вектор исключения стандартными средствами компилятора:
#pragma vector = 0x0000018
__irq __arm void IRQ_Switch() {
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();
AT91C_BASE_AIC->AIC_EOICR = 0;
}


void Handler1() {
...........
}
void Handler2() {
...........
}


1)
Цитата
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();

Что означает (void (*)void))? У меня и компилятор ошибку выдает: expected a field name.
Можно подробнее описать этот момент.
2) Получается в конце функции
Цитата
void Handler1() { ...........}
не надо обнулять
AIC_EOICR?
Заранее благодарен!
3) Функция Handler1() соответствует источнику прерывания PID1?

Сообщение отредактировал Bulat - Apr 6 2007, 08:17
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Apr 6 2007, 09:34
Сообщение #5


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Цитата(Bulat @ Apr 6 2007, 08:47) *
1)
Что означает (void (*)void))? У меня и компилятор ошибку выдает: expected a field name.
Можно подробнее описать этот момент.


приведение к типу "указатель на функцию получающую void и возвращающую void" А ругается может потому что скобочку пропустили (void (*)( void))

Цитата(Bulat @ Apr 6 2007, 08:47) *
2) Получается в конце функции не надо обнулять
AIC_EOICR?


Если обработчик прерывания общий то не стоит.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Rahhal
сообщение Apr 6 2007, 10:44
Сообщение #6





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



Пардон, если пишу глупость, но:
правильно ли я понимаю, что вектор прерывания связан с источником, а не с событием, и еслиу нас прерывания по нескольким событиям (конец передачи, конец приема и т.д.) от одного источника (UART, SPI...) ВЫЗЫВАЕТСЯ ОДИН И ТОТ ЖЕ обработчик, а в нем сам программист разбирается, что произошло за событие?
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Apr 6 2007, 11:12
Сообщение #7


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Да


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Rahhal
сообщение Apr 9 2007, 07:11
Сообщение #8





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



Спасибо!
Go to the top of the page
 
+Quote Post
Bulat
сообщение Apr 9 2007, 07:37
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(SpiritDance @ Apr 6 2007, 12:34) *
приведение к типу "указатель на функцию получающую void и возвращающую void" А ругается может потому что скобочку пропустили (void (*)( void))

Недостающую скобку я поставил, но ошибку всеравно выдает.

И еще по поводу моего третьего вопроса. Если пришел запрос на обработку прерывания от источника PID1, то вызывается функция Handler1(), если от PID2, то Handler2()?

Заранее благодарен!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 9 2007, 22:26
Сообщение #10


Гуру
******

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



Цитата(Bulat @ Apr 9 2007, 06:37) *
Недостающую скобку я поставил, но ошибку всеравно выдает.
expected a field name. Посмотрите как описан регистр AT91C_AIC_IVR в заголовочном файле вашего компилятора. Похоже, что AT91C_BASE_AIC описан не как структура и AT91C_AIC_IVR не ее член. Хотя, вы упоминаете IAR, тогда вопрос: какой заголовочный файл (ioAT91xxxxx.h) вы используете?
Цитата(Bulat @ Apr 9 2007, 06:37) *
И еще по поводу моего третьего вопроса. Если пришел запрос на обработку прерывания от источника PID1, то вызывается функция Handler1(), если от PID2, то Handler2()?
Будет вызван тот Handler, адрес которого вы занесете в соответствующий регистр AIC_SVR при инициализации, например:
Код
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (uint32_t)Handler1;
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SPI] = (uint32_t)Handler2;
строка (void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)(); дословно означает следующее: взять число из регистра AT91C_AIC_IVR, представить себе, что это адрес функции и вызвать функцию по этому адресу. После возврата из функции программа попадет на следующую команду, т.е. на AT91C_BASE_AIC->AIC_EOICR = 0, как и с обычной функцией. Адрес в AT91C_AIC_IVR заносит контроллер прерываний (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
SpiritDance
сообщение Apr 10 2007, 09:36
Сообщение #11


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Цитата(Сергей Борщ @ Apr 9 2007, 23:26) *
Как он это делает - попробуйте понять из описания контроллера.

biggrin.gif


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Sergei_K
сообщение Apr 10 2007, 12:24
Сообщение #12


Участник
*

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



Здравствуйте. У меня та же проблема, что у автора.. разбираюсь с прерываниями.. smile.gif
Собсно, заношу в программу код:

__irq __arm void IRQ_Handler1() {



AT91C_BASE_AIC->AIC_EOICR = 0;
}


При компиляции выдает ошибки:

main.c(52): error: #40: expected an identifier
main.c(52): error: #1021: __irq functions must return no result

При занесении:

__irq __arm void IRQ_Switch() {
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();
AT91C_BASE_AIC->AIC_EOICR = 0;
}


void Handler1() {

}
void Handler2() {

}

к ним добавляется ошибка:

main.c(53): error: #134: expected a field name

Таким образом, это навевает следующий вопрос: можно ли вобще таким образом работать в Keil (именно в нем я и работаю smile.gif ), а если можно - как избавиться от этих ошибок... Если нет - то как с ними работать..
Возможно, если бы знающие люди выложили более полный код (пример) и вопросы бы отпали smile.gif

P.S. Эх.. старый добрый 51.. как все было просто smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 10 2007, 14:23
Сообщение #13


Гуру
******

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



Цитата(Sergei_K @ Apr 10 2007, 11:24) *
Таким образом, это навевает следующий вопрос: можно ли вобще таким образом работать в Keil
Примеры были под IAR. Похоже, у кейла нет ключевого слова __arm, именно на него и ругается компилятор (expected an identifier, __irq functions must return no result). Посмотрите в хелпе как описать arm-функцию.
Цитата(Sergei_K @ Apr 10 2007, 11:24) *
error: #134: expected a field name
Пришлите почтой заголовочный файл с описанием SFR от кейла, посмотрю в чем тут дело.


--------------------
На любой вопрос даю любой ответ
"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
Sergei_K
сообщение Apr 11 2007, 12:21
Сообщение #14


Участник
*

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



С arm-функцией разобрался, спасибо...
Насчет заголовочного файла - вашу почту не нашел, потому выкладываю прямо здесь...
Прикрепленные файлы
Прикрепленный файл  AT91SAM7X256.rar ( 26.53 килобайт ) Кол-во скачиваний: 53
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 11 2007, 12:38
Сообщение #15


Гуру
******

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



Цитата(Sergei_K @ Apr 11 2007, 11:21) *
Насчет заголовочного файла - вашу почту не нашел, потому выкладываю прямо здесь...
"Какой осел, какой осел!" Писал эту строчку сразу в форум, вот потому и ошибка. Должно быть:
Код
(void (*)(void))(AT91C_BASE_AIC->AIC_IVR)();
или (void (*)(void))(AT91C_AIC_IVR)();
Я всегда пользуюсь вариантом с размещением по вектору команды
Код
        LDR        PC, AT91C_AIC_IVR


--------------------
На любой вопрос даю любой ответ
"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

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

 


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


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