Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ошибка с прерываниями Nios2
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
torik
Имеем PIO 8 бить вход с прерыванием по переднему фронту. IRQ=2 в сопсбилдере.
Нужно обработать прерывания от него.
Делаем все по учебнику:

Код
static void handle_button_interrupts(void* context, alt_u32 id) {
    
СЮДА ХОТЕЛОСЬ БЫ ПОПАСТЬ
    /* cast the context pointer to an integer pointer. */
    volatile int* edge_capture_ptr = (volatile int*) context;
    /*
    * Read the edge capture register on the button PIO.
    * Store value.
    */
    *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_2_BASE);
    /* Write to the edge capture register to reset it. */
    IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_2_BASE, 0);
    /* reset interrupt capability for the Button PIO. */
    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_2_BASE, 0xff);
}

// Настройка прерывания от PIO_2
static void init_button_pio() {
    /* Recast the edge_capture pointer to match the
    alt_irq_register() function prototype. */
    void* edge_capture_ptr = (void*) &edge_capture;
    /* Enable all 4 button interrupts. */
    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_2_BASE, 0xff);
    /* Reset the edge capture register. */
    IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_2_BASE, 0x0);
    /* Register the ISR. */
    alt_irq_register(PIO_2_IRQ, edge_capture_ptr, handle_button_interrupts);
}


Код
...
   init_button_pio();
...

Что получается - глядим дебагером. Когда доходит до одной из функций alt_irq_ччч (к примеру alt_irq_register, а в ней alt_irq_disable_all...) получаем сообщение: "Source not found."

Что это значит, ошибка где? Все что не касается прерываний этого PIO работает нормально...
Волощенко
Цитата(torik @ Feb 27 2008, 14:35) *
Что это значит, ошибка где? Все что не касается прерываний этого PIO работает нормально...

Аналогичная ситуация. Вот, такой же текст, только на 4-е кнопки (BUTTON_PIO по SOPC):
........
volatile int edge_capture;
........
static void handle_button_interrupts(void* context, alt_u32 id)
{volatile int* edge_capture_ptr = (volatile int*) context;
*edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0);
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf);
}
static void init_button_pio()
{void* edge_capture_ptr = (void*) &edge_capture;
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0);
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf);
alt_irq_register(BUTTON_PIO_IRQ, edge_capture_ptr, handle_button_interrupts);
}

int main()
{
........
init_button_pio();
........

}

Только я отлаживал в железе. Все работает в другой программе при программном опросе через 1мс. А при таком, с прерыванием, похоже, что в handle_button_interrupts совсем не заходит (ставил там ловушки). Вроде все по учебнику, а не понятно...
Функция alt_irq_register() возвращает ноль (проверено), она же должна разрешить прерывания (так написано в учебнике).
Кто уже осилил прерывания? Что еще здесь не так?
torik
Да это тот же код чт и у меня - его можно найти в примерах (board_diagnostic) и в хандбуке... Так же пришлось пока делать через опрос в основном цикле.
Думается мне, что тут где-то скрывается мое недопонимание. Что-то общее быть между неработой прерываний, дма через функции... может это alt_? smile.gif
RHnd
Цитата(torik @ Feb 28 2008, 09:04) *
Да это тот же код чт и у меня - его можно найти в примерах (board_diagnostic) и в хандбуке... Так же пришлось пока делать через опрос в основном цикле.
Думается мне, что тут где-то скрывается мое недопонимание. Что-то общее быть между неработой прерываний, дма через функции... может это alt_? smile.gif

Слушайте, ну я точно помню, что брал кусок с обработкой прерывания от кнопок из примера. И работало. Будет возможность - посмотрю.
torik
Ага, погляди заодно аппаратную часть - может дело в этом. Какой номер IRQ, какие прерывания еще... (хотя это не должно влиять).
Волощенко
Нашел, наконец, свою ошибку, заработало!
Нужно в непосредственном обработчике прерывания static void handle_button_interrupts() убрать сроку с IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); , то есть не торопиться открывать маску для последующих прерываний. В edge_capture хранится флаг нажатой клавиши, его нужно обрабатывать уже другой программой (например в main с циклом 1мс), а уже в этой программе выполнить IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); , соответственно сбросив здесь и edge_capture. Ну и нужно еще немного побороться с дребезгом контактов от клавиш.
Кстати, в тестовом примере из board_diag.c, так и сделано.
torik
Вероятно, ты ошибаешься.
Если "обрабатывать надо уже другой программой" то мне не нужен обработчик прерываний, получается бред.
Если не секрет, выложите код, поглядим...
torik
Кроме того речь идет об инициализации прерываний, еще до того как попали в обработчик...

Так, кажется подобрался к причине. Требуется совет, где про это прочитать или объяснение в чем дело).
Итак, если у нас имеется:

Код
int main (void) __attribute__ ((weak, alias ("alt_main")));
int alt_main (void) {
...


То прерывания не работают, но зато программа прошивается через flash programer и работает

Код
int main (void);
int main (void) {
...


В этом случае прерывания работают! Но программа работает только RunAs->Nios2Hardware. После прошивки через flash programer не работает программа вообще!
Кто разбирался с этим, поясните пожалуйста...


Разница между main() и alt_main() впринципе ясна. Непонятно как правильно с помощью флешпрограмера прошить проект иммено в варианте с main(). С alt_main() достаточно нажать кнопку програмирования)))
Волощенко
Цитата(torik @ Feb 28 2008, 23:53) *
Если не секрет, выложите код, поглядим...
Проблем показать нет, если кому-то это интересно.
В моем DK-NIOS-2S60N, есть также четыре кнопки и восемь светодиодов. Для начала я включал светодиоды, нажатием кнопок, используя режим опроса (polling). Дальше решил освоить прерывания по следующему алгоритму:
В исходном состоянии кнопка отжата (единица). При нажатии идет дребезг, кстати, от него сразу прерывание, потом ноль с небольшой продолжительностью, опять дребезг и уже опять исходное состояние. Одно нажатие кнопки переключает свечение светодиода. Биты в регистре edgecapture срабатывают по спаду (настройки в SOPC). Тексты, в режиме не полной гласности, в приложении.
По посту от 29.02.08 пока ничем помочь не могу.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.