Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Програмирование MicroBlaze с fast interrupt
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
misyachniy
XPS Xilinx при синтезе контроллера прерываний для Microblaze предлагает режим быстрых прерываний.
В контроллере прерываний есть регистр(ы) IVAR для хранения векторов прерываний.
Xilinx предоставляет примеры в которых есть функция XIntc_ConnectFastHandler()
В которой происходит запись в эти регистры.
Код
int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id,  XFastInterruptHandler Handler)

XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), (u32) Handler);

Я сгенерил тестовый пример контроля периферии.Но в нем не вызывается эта функция.
В интернете поиск по слову "XIntc_ConnectFastHandler" не дает ни одной ссылки.

Я попробовал врукопашную завести адреса двух функций в регистры IVAR.
Адреса прописываются и считываются.
Разрешение прерывания и быстрый режим тоже.
Но прерывание больше одного раза не вызывается.
Судя по объявлению таблицы прерываний для обычного режима прерываний:
Код
void __interrupt_handler (void) __attribute__ ((interrupt_handler));

void __interrupt_handler(void)
{
    /* The compiler saves all volatiles and the MSR */
    MB_InterruptVectorTable.Handler(MB_InterruptVectorTable.CallBackRef);
    /* The compiler restores all volatiles and MSR, and returns from interrupt */
}

компилятору нужно принудительно указать, что это функция прерывания.
По аналогии с процессорами ARM я попробовал скомпилировать программу с двумя функциями и дополнительными атрибутами.
Код
__attribute__ ((interrupt_handler)) void Int_Timer0 (void)

В результате получаю ошибку:
Цитата
symbol `_interrupt_handler' is already defined

Для такой ошибки на сайте Xilinx есть только решение для ОС Xilkernel. И тоже похоже на обычный вызов прерывания, когда один обработчик опрашивает в контроллере прерывания индекс прерывания и запускает по таблице векторов, хранящейся в оперативной памяти, требуемую функцию.

Если только одну функцию в программе объявляю с указанным атрибутом, то она успешно вызывается многократно.

Как правильно запрограммировать контроллер на быстрые прерывания?
misyachniy
Для генерирования корректного кода компиляторов для функций быстрого прерывания требуются следующие указания компилятору

1) Указать прототипы всех функций прерываний с атрибутом.
Цитата
interrupt_handler attribute

To distinguish an interrupt handler from a sub-routine, mb-gcc looks for an attribute
(interrupt_handler) in the declaration of the code.
This attribute is defined as follows:

void function_name () __attribute__ ((interrupt_handler));

Note: The attribute for the interrupt handler is to be given only in the prototype and not in the definition.

Основание: стр 123, файл «est_rm.pdf»
Embedded System
Tools Reference
Manual
EDK
UG111 (v14.2) July 25, 2012

2) Атрибут должен быть fast_interrupt
Цитата
With low-latency interrupt mode, control is directly passed to the interrupt handler for each individual interrupt utilizing this mode. In this case, it is the responsibility of each handler to save and restore used registers. The MicroBlaze C compiler (mb-gcc) attribute fast_interrupt is available to allow this task to be performed by the compiler:
void interrupt_handler_name() __attribute__((fast_interrupt));

Основание: стр 150, файл «mb_ref_guide.pdf»

MicroBlaze Processor
Reference Guide
Embedded Development Kit
EDK 14.2
UG081 (v14.2)

Кроме этого при индивидуальном разрешении прерываний в контроллере прерываний, например, так:
Код
Xil_Out32(XPAR_AXI_INTC_0_BASEADDR + XIN_CIE_OFFSET, mask);

Работает только последнее разрешенное прерывание.
Нужно разрешать сразу все:
Цитата
I've put the mask in all the XGpio_InterruptEnable() functions to 0xff;
For example:
XGpio_InterruptEnable(&gpPB,XPAR_DIPS_4BIT_IP2INTC_IRPT_MASK);
to
XGpio_InterruptEnable(&gpPB, 0xff);

Основание:
http://forums.xilinx.com/t5/Embedded-Proce...-p/96090/page/2
AVR
Я правильно понимаю что проблема, описанная в этой теме, уже решена?
Если можно, я влезу со своим вопросом?

У меня не получается вообще заставить работать прерывания от GPIO (я пока только начинаяю осваивать MicroBlaze). Получается читать пин - нажимаю pushbutton и вижу единицу, а отпускаю вижу ноль, т.е. настраивать напрвление IO и читать значение порта я научился. Теперь проблема заставить работать прерывания по GPIO.

В качестве примера использую xgpio_intr_example.c, но ни такой API через XGpio ни low level примеры так и не помогли мне получить рабочий вариант...

Есть ли какие-нибудь способы отладки проблемы с прерываниями? Какие регистры надо проверить чтобы убедиться что оно должно работать?

Нажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файла

В файле test_i2c.txt
Код
void gpio_interrupt(void *callback_ref)
{
    xil_printf("GPIO interrupt!\n\r");
    irq_handled = true;
}

bool test_i2c::init_intc()
{
    int res;

    res = XIntc_Initialize(&intc, XPAR_INTC_0_DEVICE_ID);
    if(res != XST_SUCCESS) return false;

    XIntc_Connect(&intc, XPAR_INTC_0_GPIO_0_VEC_ID, (Xil_ExceptionHandler)gpio_interrupt, &gpio);
    XIntc_Enable(&intc, XPAR_INTC_0_GPIO_0_VEC_ID);
    res = XIntc_Start(&intc, XIN_REAL_MODE);
    if(res != XST_SUCCESS) return false;

    XGpio_InterruptEnable(&gpio, XPAR_GENERIC_GPIO_IP2INTC_IRPT_MASK);
    XGpio_InterruptGlobalEnable(&gpio);

    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &intc);
    Xil_ExceptionEnable();

    return true;
}

bool test_i2c::init_gpio()
{
    XGpio_Initialize(&gpio, XPAR_GENERIC_GPIO_DEVICE_ID);
    XGpio_SelfTest(&gpio);
    XGpio_SetDataDirection(&gpio, 1, 0x01);
    return true;
}

test_i2c::test_i2c()
{
    bool ok = false;
    init_gpio();
    ok = init_intc();
    if(ok) xil_printf("intc OK\n\r");
intc OK - пишет, т.е. инициализация вроде бы проходит. В системе есть один GPIO порт 8-ми битный.
misyachniy
В тексте програмы не видно програмного разрешения прерывания - microblaze_enable_interrupts();
Так же я рекомендовал бы проверить присоединение вывода прерывания от контроллера прерsваний (рис check_hw_int_conection) .
AVR
Цитата(misyachniy @ Oct 30 2012, 20:37) *
В тексте програмы не видно програмного разрешения прерывания - microblaze_enable_interrupts();
Так же я рекомендовал бы проверить присоединение вывода прерывания от контроллера прерsваний (рис check_hw_int_conection) .
Спасибо за ответ! Всё было в порядке, я смотрел и железную часть и софт, всё перерыл, оказалось я неправильно маску задал для XGpio_InterruptEnable (тут надо указать например маску 0x01 если нулевой вывод например 8-мибитного GPIO порта используется), потерялся в трёх соснах...

Судя по xgpio_intr_tapp_example.c microblaze_enable_interrupts() не требуется, у меня и без этого вызова работает когда работаю со структурой XIntc и XIntc_Enable + XIntc_Start... а эта функция для low level API видимо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.