Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с прерываниями от ядра
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Грендайзер
Здравствуйте, коллеги. Работую с Nios II и понадобилось подключить собственное ядро. Написал, подключил - всё хорошо, кроме прерываний. Способы подключения ядра к процессору на рисунке. В первом случае, процессор, после того как происходит прерывание, просто останавливается и всё (в режиме отладки заходит в какую то неведомую функцию после выхода из которой процес опять повторяется и он опять в неё заходит). Во втором случае, процессор нормально уходит в прерывание. В третьем, зависит от того что произошло ранеьше. Если зажать кнопку прерывания, то после ресета процессор входит в обработчик прерывания, если же кнопку не нажимать , то после ресета ядро генерит прерывание и проц столбинеет. Возможно кто то уже напарывался. Буду очень благодарен за помощь. Так же ниже приведу код на с.
Код
#include <stdio.h>
#include "io.h"
#include "system.h"
#include "alt_types.h"
#include "sys/alt_irq.h"

void chu_chu_subprog(void* context, alt_32 id);

void* context;
alt_32 id = 0;

alt_u32 a = 0;

int main()
{
    alt_irq_register(CHU_CHU_IRQ, context, (void*)chu_chu_subprog); // указываем ф-цию обработки прерывания

    while(1)
    {

        IOWR(CHU_CHU_BASE, 0, 6);     // данные в my_core
        IOWR(CHU_CHU_BASE, 1, 7);     // данные в my_core
        IOWR(CHU_CHU_BASE, 3, 1);     // маска прерывания в my_core
        IOWR(CHU_CHU_BASE, 2, 1);     // запуск my_core на выполнение

        a = IORD(CHU_CHU_BASE, 4);     // читаем данные с ядра

        IOWR(LED_BASE, 0, a);         // выводим результат работы ядра на светодиоды
    }

return 0;
}

void chu_chu_subprog(void* context, alt_32 id) // если произошло прерывание выполнить ф-цию
  {
        while(1)
        {IOWR(LED_BASE, 0, 0x55);}
        return;
  }
serjj
Здравствуйте.
Код
void chu_chu_subprog(void* context, alt_32 id) // если произошло прерывание выполнить ф-цию
  {
        while(1)
        {IOWR(LED_BASE, 0, 0x55);}
        return;
  }

Первое, что смутило: у вас в обработчике бесконечный цикл.

Регистрация:
Код
alt_irq_register(CHU_CHU_IRQ, context, (void*)chu_chu_subprog);

Я регистрирую вот так, попробуйте мб:
Код
alt_irq_register(CHU_CHU_IRQ, NULL, chu_chu_subprog);


Приведите если не сложно код на HDL как у вас формируется сигнал прерывания и как он снимается.
В функции обработчике нет снятия флага прерывания. Оно снимается автоматически?
Проверьте дефайн CHU_CHU_IRQ - он точно содержит то что надо? Если тут напутать, то проц улетит в непонятные дебри.
Грендайзер
Не заработало sad.gif В дефайне CHU_CHU_IRQ - 0 (в процессорной системе прерывание генерит лишь моё ядро). Приведу коды ядра. Оно эксперементальное и производит лишь логическое умножение чисел в регистрах а и b. Привожу как само ядро так и файл со связующей логикой. Прерывание с ядра генерится в файле and_core а генерация с кнопки добавляется в файле my_core_IRQ. Так же приведу код из .sdc файла:
Код
derive_clock_uncertainty
create_clock -period 25MHz -name {clk} [get_ports {clk}]


Так, никому не дышать... Кожись начинает выходить... Да кажись вышло. Увеличил длительность существования сигнала IRQ до 255 тактовых циклов (i = x"11") и прерывание вроде заработало. Сейчас ещё поэксперементирую.
serjj
У вас прерывание ничем не маскируется. Процу приходит прерывание, оно еще не зарегестировано, как он будет его обрабатывать? Снятие прерывания лучше сделать через процессор, чтением или сбросом регистра статуса прерываний (или чего-нибудь подобного), тогда оно будет гарантировано ловиться процессором. Хорошая практика для инициализации прерываний - глобальное разрешение прерываний - регистрация прерываний - локальное разрешение (в вашем случае разрешение прерывания от вашего ядра)
Грендайзер
Нет, регистр маски есть. Просто я его закоментил временно (да и отсутствие маски не объясняет выборочного срабатывания от кнопки). Впрочем сейчас всё и впрямь заработало, как я уже написал в предыдущем сообщении. Если счётчик i = "11111111" всё прекрасно работает, но вот стоит его остановить на числе "01111111" как выскакивает непонятная ерунда. Когда моделтровал работу процессора в Modelsim я конечно видел, что бесплатная верся не очень расторопна, но 255 тактов, что б понять, что прерывание произошло.... blink.gif
P.S.
serjj, большое спасибо, что отозвались!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.