|
|
  |
Обработка прерывания от SPI, at91sam7s256 |
|
|
|
Mar 30 2007, 10:22
|

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

|
1 гыгы В даташите от атмела есть загадочные места.  На самом деле узнать 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.
|
|
|
|
|
Apr 6 2007, 07:47
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Apr 6 2007, 09:34
|

Дух погибшего транзистора
   
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Apr 6 2007, 10:44
|
Группа: Новичок
Сообщений: 6
Регистрация: 3-04-07
Пользователь №: 26 726

|
Пардон, если пишу глупость, но: правильно ли я понимаю, что вектор прерывания связан с источником, а не с событием, и еслиу нас прерывания по нескольким событиям (конец передачи, конец приема и т.д.) от одного источника (UART, SPI...) ВЫЗЫВАЕТСЯ ОДИН И ТОТ ЖЕ обработчик, а в нем сам программист разбирается, что произошло за событие?
|
|
|
|
|
Apr 9 2007, 07:11
|
Группа: Новичок
Сообщений: 6
Регистрация: 3-04-07
Пользователь №: 26 726

|
Спасибо!
|
|
|
|
|
Apr 9 2007, 07:37
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(SpiritDance @ Apr 6 2007, 12:34)  приведение к типу "указатель на функцию получающую void и возвращающую void" А ругается может потому что скобочку пропустили (void (*)( void)) Недостающую скобку я поставил, но ошибку всеравно выдает. И еще по поводу моего третьего вопроса. Если пришел запрос на обработку прерывания от источника PID1, то вызывается функция Handler1(), если от PID2, то Handler2()? Заранее благодарен!
|
|
|
|
|
Apr 9 2007, 22:26
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Apr 10 2007, 12:24
|
Участник

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

|
Здравствуйте. У меня та же проблема, что у автора.. разбираюсь с прерываниями.. Собсно, заношу в программу код: __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 (именно в нем я и работаю  ), а если можно - как избавиться от этих ошибок... Если нет - то как с ними работать.. Возможно, если бы знающие люди выложили более полный код (пример) и вопросы бы отпали P.S. Эх.. старый добрый 51.. как все было просто
|
|
|
|
|
Apr 10 2007, 14:23
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Apr 11 2007, 12:21
|
Участник

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

|
С arm-функцией разобрался, спасибо... Насчет заголовочного файла - вашу почту не нашел, потому выкладываю прямо здесь...
|
|
|
|
|
Apr 11 2007, 12:38
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|