|
|
  |
alt_irq_register()? |
|
|
|
Dec 27 2010, 06:25
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(vadimuzzz @ Dec 27 2010, 14:14)  обычно там передается указатель на файл устройства, от которого приходит прерывание. если не нужен, можно 0 передавать. что значит "файл устройства"? Это если я использую ос, например linux, то я там должен передать указатель на файл, например, /dev/tty0. А если ос нет? Если я пишу без ос и хочу написать обработчик прерывания от uart-a, что туда передавать? Цитата если не нужен Как определить - нужен он мне или не нужен? Есть где-нибудь более полное описание этой функции?
Сообщение отредактировал juvf - Dec 27 2010, 06:26
|
|
|
|
|
Dec 27 2010, 07:11
|

Гуру
     
Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988

|
Цитата что значит "файл устройства"? я не совсем корректно выразился. там передается указатель на структуру устройства, имя файла - одно из полей этой стр-ры. например: Код /* SGDMA Device Structure */ typedef struct alt_sgdma_dev { alt_llist llist; // Device linked-list entry const char *name; // Name of SGDMA in SOPC System void *base; // Base address of SGDMA alt_u32 *descriptor_base; // reserved alt_u32 next_index; // reserved alt_u32 num_descriptors; // reserved alt_sgdma_descriptor *current_descriptor; // reserved alt_sgdma_descriptor *next_descriptor; // reserved alt_avalon_sgdma_callback callback; // Callback routine pointer void *callback_context; // Callback context pointer alt_u32 chain_control; // Value OR'd into control reg } alt_sgdma_dev; посмотрите, наверное и для UART такая же есть. Цитата Если я пишу без ос и хочу написать обработчик прерывания от uart-a, что туда передавать? вы сами должны решить, нужны вам такие красивости в виде структур. потому что то же самое можно сделать через регистры устройства. а все эти структуры - просто обертки к ним. Цитата Есть где-нибудь более полное описание этой функции? в Software Developer`s Handbook есть описание API HAL, там в конец список функций.
|
|
|
|
|
Feb 18 2012, 04:56
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Цитата(vadimuzzz @ Dec 27 2010, 09:14)  обычно там передается указатель на файл устройства, от которого приходит прерывание. если не нужен, можно 0 передавать. Доброго времени! Никак не получается вызвать свою процедуру по пррыванию. Сделал вроде все как описано, но не получается. В SOPC назначил приоритет, в NIOS SBT, регистрирую таким образом: CODE static void ISR_Name();
void Registration(alt_u32 base, alt_u8 irq_number) { contx.base = base; alt_irq_register(irq_number, &contx, ISR_Name); }
прерывание возникает каждую ms но не вызывается процедура ISR_Name... не заходит у меня туда отладчик... Как считаете, куда нужно обратить ещё внимание??? Можетчего-то забыл? Кстати, в руководстве описана функция alt_irq_register, которая располагается в файле <sys/alt_irq.h>, а реально я там не смог её найти, вместо неё описана функция alt_ic_isr_register()... Я сначало подумал, что на этапе компиляции даст ошибку, о том что данной функции нет, но нет...всё прошло нормально...И непоняно откуда он её берет...
--------------------
С Уважением...
|
|
|
|
|
Feb 18 2012, 06:50
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(Fynjisx @ Feb 18 2012, 14:56)  Кстати, в руководстве описана функция alt_irq_register, которая располагается в файле <sys/alt_irq.h>, а реально я там не смог её найти, вместо неё описана функция alt_ic_isr_register()... Я сначало подумал, что на этапе компиляции даст ошибку, о том что данной функции нет, но нет...всё прошло нормально...И непоняно откуда он её берет... alt_irq_register - это сейчас устаревшая функция, вместо нее спользуется alt_ic_isr_register. И функцию alt_irq_register выкинули из sys/alt_irq.h в файл, название которого сейчас не скажу - какой-то набор из слов "приватный" (prev), irq, alt, legacy. Можете все-таки найти функцию поиском. По существу вашей проблемы сказать что либо трудно. Остальные прерывания работают? Бит, соответствующий прерыванию в регистре ienable выставлен? Вы точно уверены, что флаг прерывания выставляется?
|
|
|
|
|
Feb 18 2012, 14:45
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Цитата(barabek @ Feb 18 2012, 09:50)  alt_irq_register - это сейчас устаревшая функция, вместо нее спользуется alt_ic_isr_register. И функцию alt_irq_register выкинули из sys/alt_irq.h в файл, название которого сейчас не скажу - какой-то набор из слов "приватный" (prev), irq, alt, legacy. Можете все-таки найти функцию поиском. понятно, спасибо... Цитата(barabek @ Feb 18 2012, 09:50)  Остальные прерывания работают? остальных пока нет, это первое... попробовал от системного таймера прерваться, для этого тоже зарегал функцию подобным образом...но такая же байда - кручусь в бесконечном цикле и ни каких намеков на переброс в функцию-обработчик... Цитата(barabek @ Feb 18 2012, 09:50)  Бит, соответствующий прерыванию в регистре ienable выставлен? Вы точно уверены, что флаг прерывания выставляется? да, в режиме отладки когда уже зарегил ф-ию, кручусь в бесконечном цикле и жду прерывания, ienable в окне registers при этом равен 1. Цитата(barabek @ Feb 18 2012, 09:50)  Вы точно уверены, что флаг прерывания выставляется? запрос прерывания точно выставляется, смотрел сигналтапом. Кстати это мой собственный компонент... Может чего то не так сделал? но в sopc в принципе только выставляю приоритет, а в sbt при регистрации использую базовый адрес компонента и номер запроса... грешил на свой компонент, что говорить, но у меня даже от таймера не получается прерваться... что то я не так пишу, какие еще тонкости могут быть??? может static не надо писать у функции обработчика или в режиме отладки невозможно попасть в обработчик по прерыванию... Если произойдет прерывание от таймера то куда нужно глядеть, на какой регистр?
--------------------
С Уважением...
|
|
|
|
|
Feb 19 2012, 01:08
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(Fynjisx @ Feb 19 2012, 00:45)  остальных пока нет, это первое... попробовал от системного таймера прерваться, для этого тоже зарегал функцию подобным образом...но такая же байда - кручусь в бесконечном цикле и ни каких намеков на переброс в функцию-обработчик... да, в режиме отладки когда уже зарегил ф-ию, кручусь в бесконечном цикле и жду прерывания, ienable в окне registers при этом равен 1. грешил на свой компонент, что говорить, но у меня даже от таймера не получается прерваться... что то я не так пишу, какие еще тонкости могут быть??? может static не надо писать у функции обработчика или в режиме отладки невозможно попасть в обработчик по прерыванию... Если произойдет прерывание от таймера то куда нужно глядеть, на какой регистр? Функции прерывания написаны в таком виде void COM_ISR(void * Context,alt_u32 id) (или при Enhansed void COM_ISR(void * Context) )? Соответствующий бит разрешения всех прерываний в регистре status выставлен? При возникновении (по сигналтапу или по "ЗубДаюВыставлен") флага прерывания соответствующий бит в ipending (такой же по номеру как и в ienable) возводится? И еще нужно попробовать поставить брекпоинт в обработчике прерываний alt_irq_handler. UPD А для таймера должен быть выставлен бит ITO и с приходом переполнения выставляется флаг TO. Все это можно посмотреть в memory. Добейтесь сперва работоспособности прерывания от таймера.
|
|
|
|
|
Feb 19 2012, 03:30
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Давайте по порядку. Цитата(barabek @ Feb 19 2012, 04:08)  Добейтесь сперва работоспособности прерывания от таймера. Создаю такой таймер к примеру, рис.1. Цитата(barabek @ Feb 19 2012, 04:08)  Функции прерывания написаны в таком виде void COM_ISR(void * Context,alt_u32 id) (или при Enhansed void COM_ISR(void * Context) )? Пишу так: CODE int io = 0; void COM_ISR(void* context, alt_u32 id) { io = io + 1; // здесь я поставил точку прерывания слева } ... int main (void) { ... alt_irq_register(SYS_TIMER_IRQ, 0, COM_ISR); ... alt_u16 states; alt_u16 control; //ну и чем-то чтобы себя занять, кручусь в цикле ожидая прерывания от таймера while(1) { states = IORD(SYS_TIMER_BASE, 0); control = IORD(SYS_TIMER_BASE, 1); i = i + 1; } ... }
в модуле system.h то, что касается таймера описано так: CODE #define ALT_MODULE_CLASS_sys_timer altera_avalon_timer #define SYS_TIMER_ALWAYS_RUN 1 #define SYS_TIMER_BASE 0x0 #define SYS_TIMER_COUNTER_SIZE 32 #define SYS_TIMER_FIXED_PERIOD 1 #define SYS_TIMER_FREQ 50000000u #define SYS_TIMER_IRQ 2 #define SYS_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0 #define SYS_TIMER_LOAD_VALUE 14ULL #define SYS_TIMER_MULT 2.0E-8 #define SYS_TIMER_NAME "/dev/sys_timer" #define SYS_TIMER_PERIOD 15 #define SYS_TIMER_PERIOD_UNITS "clocks" #define SYS_TIMER_RESET_OUTPUT 0 #define SYS_TIMER_SNAPSHOT 0 #define SYS_TIMER_SPAN 32 #define SYS_TIMER_TICKS_PER_SEC 3333334u #define SYS_TIMER_TIMEOUT_PULSE_OUTPUT 0 #define SYS_TIMER_TYPE "altera_avalon_timer"
Далее компилирую обновленные файлы, нажимаю на "жучка" и перехожу в режим "debug nios" В режиме отладки перед тем как зайти в функцию регистрации смотрю, на всплывающую подсказку, которая говорит, что SYS_TIMER_IRQ = 0, хотя в system.h он определен как SYS_TIMER_IRQ = 2 (рис.2). Ну я думаю это просто глюк..У Вас наверное также... перед выходом из функции регистрации rc = 0, что говорит, что нормально зарегилась... Цитата Соответствующий бит разрешения всех прерываний в регистре status выставлен? После того, как я начинаю крутиться в цикле, который уже упоминал, дожидаясь события смотрю в окно register (рис.3) я там выставил двоичный формат, мне так проще смотреть... Цитата А для таймера должен быть выставлен бит ITO и с приходом переполнения выставляется флаг TO. Все это можно посмотреть в memory. долго жму F5, но бит ITO не выставляется... рис.4 тогда иду ва-банк и сам его выставляю ручками рис.5(черт его знает почему он не выставляется автоматом) Цитата При возникновении флага прерывания соответствующий бит в ipending (такой же по номеру как и в ienable) возводится? Далее перехожу на вкладку register и там ipending подтверждается рис.6. Цитата И еще нужно попробовать поставить брекпоинт в обработчике прерываний alt_irq_handler. breakpoint уже сделал в теле COM_ISR (. вот такая ситуация... Уже неделю на это потратил...Где-то я не то делаю...Но где? не могу понять...
Сообщение отредактировал Fynjisx - Feb 19 2012, 03:31
Эскизы прикрепленных изображений
--------------------
С Уважением...
|
|
|
|
|
Feb 19 2012, 05:58
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(Fynjisx @ Feb 19 2012, 13:30)  Далее компилирую обновленные файлы, нажимаю на "жучка" и перехожу в режим "debug nios" В режиме отладки перед тем как зайти в функцию регистрации смотрю, на всплывающую подсказку, которая говорит, что SYS_TIMER_IRQ = 0, хотя в system.h он определен как SYS_TIMER_IRQ = 2 (рис.2). Ну я думаю это просто глюк..У Вас наверное также... нет, у меня в nios sbt всплывающее окошко показывает именно то что нужно - в соответствии с system.h Цитата перед выходом из функции регистрации rc = 0, что говорит, что нормально зарегилась... У Вас на третьем рисунке уже вроде как флаг прерывания взведен, если судить по ipending, так же как и на рисунке 6. Цитата долго жму F5, но бит ITO не выставляется... рис.4 тогда иду ва-банк и сам его выставляю ручками рис.5(черт его знает почему он не выставляется автоматом) Флаг этот ITO не должен сам выставляться, его должны Вы выставить. Цитата Далее перехожу на вкладку register и там ipending подтверждается рис.6. breakpoint уже сделал в теле COM_ISR (. вот такая ситуация... Уже неделю на это потратил...Где-то я не то делаю...Но где? не могу понять... Непонятно почему на 3-ем рисунке у Вас уже выставился флаг. Ладно потом разберемся  А попробуйте дополнительно поставить брекпоинт на одной из строчек бесконечного цикла, но уже после запуска. И после того, как Вы выставите флаг IT0 (програмно или насильно через соответствующее окно) Вполне возможно что в этом случае у Вас остановки не случится, т.к. программа крутится внутри alt_irq_handler.c тщетно ища обработчик (из-за несоответствия по каким-то причинам SYS_TIMER_IRQ тому что нужно). И брекпоинт внутри handler поставьте, забрав его из своего обработчика. А дальше в пошаговом режиме, если все правильно, handler вызовет Ваш обработчик.
|
|
|
|
|
Feb 19 2012, 06:18
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Цитата(barabek @ Feb 19 2012, 08:58)  И брекпоинт внутри handler поставьте, забрав его из своего обработчика. из обработчика COM_ISR убрать breakpoint? А где искать этот handler?
--------------------
С Уважением...
|
|
|
|
|
Feb 19 2012, 06:27
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(Fynjisx @ Feb 19 2012, 16:18)  из обработчика COM_ISR убрать breakpoint? А где искать этот handler? Можете и оставить, просто он там не особо нужен. А alt_irq_handler() у меня лежит в PROGECT_bsp->HAL->src->irq_hanler.c Да Вы его поиском можете найти. Кнопкой с фонариком (или через меню) Search-> file search->containing text = alt_irq_handler, главное поиск настройте, чтобы он и в bsp искал.
|
|
|
|
|
Feb 19 2012, 08:46
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Цитата(barabek @ Feb 19 2012, 09:27)  Можете и оставить, просто он там не особо нужен. А alt_irq_handler() у меня лежит в PROGECT_bsp->HAL->src->irq_hanler.c
Да Вы его поиском можете найти. Кнопкой с фонариком (или через меню) Search-> file search->containing text = alt_irq_handler, главное поиск настройте, чтобы он и в bsp искал. разобрался наполовину как это работает: в момент инициализации регистрируется обработчик таймера - alt_avalon_timer_sc_irq. После регистрации в течении инициализации если происходит прерывание по таймеру, то срабатывает alt_irq_handler()(как он срабатывает не увидел); он начинает шарить по всем битам pending в поиске индекса элемента таблицы указателей зарегенных функций и как только находит, обращается по этому индексу...А там указатель обработчика таймера, о котором писал выше... И всё работает))))... Но... Дальше идет ещё какая-то инициализация... Смшная функция _do_ctor работает, в ней прерывания запрещены...потом снова разрешаются иопять всё работает... Но как только я выхожу в main, handler уже больше не вызывается!!! Должен сказать что я убрал из своего main функцию регистрации прерывания, так как таймер её имееет ещё со времен инициализации и по идее при возникновении прерывания в любом случае должен был вызватсья handler, но он не вызывается если как только я попадаю в main хотя прерывание генерится!!! Вот таккая ситуация... Что может быть???
--------------------
С Уважением...
|
|
|
|
|
Feb 19 2012, 11:02
|
студент
   
Группа: Свой
Сообщений: 571
Регистрация: 3-07-08
Из: Russia
Пользователь №: 38 712

|
Цитата(barabek @ Feb 19 2012, 12:18)  А какая у Вас версия? А то у меня при переходе с 9 на 11 тоже возникли проблемы из-за начальной инициализации У меня Eclipse - Version: 3.4.1. Quartus 9.1sp2. Цитата(barabek @ Feb 19 2012, 12:18)  Не слишком разбираясь записал вместо main alt_main, переопределив стандартную alt_main. Это даже лучше - более предсказуемый код. Очень смелый ход))) Уважаемый barabek! Нашел я то, что неправильно делаю... Не нужно было жать f5 в ожидании "чуда". Всего то навсего надо было нажать f7, но и ещё куча мелких деталей, типа: всегда снимать irq в обработчике. Как только у меня стал активизироваться handler из main, я сразу понял что дела пошли в гору) и потом уж написал, знаменитый COM_ISR, который припервой же попытке не заставил себя долго ждать). Да кстати используйте static function для пользовательских handler's, как в alter'вском коде... Спасибо за помощь...Здоровски помогли...Спасибо...
--------------------
С Уважением...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|