Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FIQ handler в микриумовском порте ucos под LPC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Velund
Сидел, изучал порт под LPC... И наткнулся вот на этот кусочек...


/*
********************************************************************************
*************************
* IRQ ISR HANDLER
*
* Description : This function is called by OS_CPU_IRQ_ISR() to determine the source of the interrupt
* and process it accordingly.
*
* Arguments : none
********************************************************************************
*************************
*/

void OS_CPU_IRQ_ISR_Handler(void)
{
PFNCT pfnct;


#if 0
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
if (pfnct != (PFNCT)0) { /* Make sure we don't have a NULL pointer */
(*pfnct)(); /* Execute the ISR for the interrupting device */
}
#else
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
while (pfnct != (PFNCT)0) { /* Make sure we don't have a NULL pointer */
(*pfnct)(); /* Execute the ISR for the interrupting device */
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
}
#endif
}


/*
********************************************************************************
*************************
* FIQ ISR HANDLER
*
* Description : This function is called by OS_CPU_FIQ_ISR() to determine the source of the interrupt
* and process it accordingly.
*
* Arguments : none
********************************************************************************
*************************
*/
void OS_CPU_FIQ_ISR_Handler(void)
{
PFNCT pfnct;


#if 0
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
if (pfnct != (PFNCT)0) { /* Make sure we don't have a NULL pointer */
(*pfnct)(); /* Execute the ISR for the interrupting device */
}
#else
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
while (pfnct != (PFNCT)0) { /* Make sure we don't have a NULL pointer */
(*pfnct)(); /* Execute the ISR for the interrupting device */
pfnct = (PFNCT)VICVectAddr; /* Read the interrupt vector from the VIC */
}
#endif
}


Может уважаемые гуру скажут - я чего то не понял, или они для скорости сделали copy/paste не вдумываясь в "физический смысл"? ;-)

В мануале на порт скользко обойден вопрос FIQ, кстати.
Velund
Смешанные чувства какие то все же возникают. Это в BSP из AN1138 - все же микриумовский исходник...
Romario
Цитата(Velund @ Apr 12 2006, 19:42) *
Смешанные чувства какие то все же возникают. Это в BSP из AN1138 - все же микриумовский исходник...


какой то из этих вариантов не правильныйsmile.gif и вообще не рабочий.
на такую же проблему натыкался, по моему, Tolik в конфе ARM на сахаре.

вроде это..
http://www.caxapa.ru/echo/arm.html?id=49584
Velund
Я про другое... Про FIQ... Там вообще copy/paste с IRQ handler'а, похоже никто даже не вникал в отличия, а уж тем более не пытался запускать... ;-)
Romario
Цитата(Velund @ Apr 12 2006, 22:39) *
Я про другое... Про FIQ... Там вообще copy/paste с IRQ handler'а, похоже никто даже не вникал в отличия, а уж тем более не пытался запускать... ;-)


а, понял. ну так это логические функции. а обработка что fiq что isr прерывания одинакова.
а уж как ее обрамить, дело программистаsmile.gif

а насчет запуска. fiq я в укосе пользую, только из нее ничего не сигналится в ось поэтому и обрамлять
ее сервисами укоса считаю дело не нужным. соответственно по теме высказать больше нечегоsmile.gif
Andy Mozzhevilov
Цитата(Velund @ Apr 13 2006, 00:39) *
Я про другое... Про FIQ... Там вообще copy/paste с IRQ handler'а, похоже никто даже не вникал в отличия, а уж тем более не пытался запускать... ;-)


В принципе, в оси с generic портом должно все нормально работать.
Получается система с 2 уровнями приоритетов, IRQ - младший, FIQ - старший.
Из области векторов нужно перейти на точки входа IRQ и FIQ, что-то типа
Код
                CODE32  ; Always ARM mode after reset

                org     0x18
irq_handler:    ldr     pc, do_irq_addr

; Constant table entries (for ldr pc) will be placed at 0x20
                org     0x38
do_irq_addr:
                DC32   OS_CPU_IRQ_ISR


и также для FIQ.

Из портовых хэндлеров IRQ и FIQ вызываются OS_CPU_IRQ_ISR_Handler() и OS_CPU_FIQ_ISR_Handler(),
объявляемых юзером. Перехватчики прерываний в порте оси сделаны так, что можно вызывать сервисы ОС как из IRQ, так и из FIQ. Надо это или нет, вопрос конкртеной задачи. Если из FIQ вызывать сервисы ОС не требуется, то можно вообще не пользовать OS_CPU_FIQ_ISR а вызывать свой обработчик fiq прямо с вектора.
В этом случае целесообразно также переписать осевую функцию OS_CPU_SR_Save(),
переопределив макроопределение NO_INT как
Код
NO_INT      EQU     0x80                    ; Mask used to disable only IRQ interrupt

что у меня и сделано.

и еще, IRQ хэндлер нужно сделать так
Код
/*
********************************************************************************
*************************
*                                     OS_CPU_IRQ_ISR_Handler
*
* Description: Обработчик прерывания ОС
*
* Arguments  : none
*
* Returns    : none
*
* Notes      : VICDefVectAddr должен быть установлен в 0 при инициализации
*
********************************************************************************
*************************
*/
#ifdef __cplusplus
extern "C"
#endif
void OS_CPU_IRQ_ISR_Handler (void)
{
    PFNCT    pfnct;

    pfnct = (PFNCT)VICVectAddr;                      /* Read the interrupt vector from the VIC         */
    while (pfnct != (PFNCT)0)                        /* Handle ALL interrupting devices                */
    {
        (*pfnct)();                                  /* Call ISR for interrupting device               */
        VICVectAddr = 0;                             /* update priority hardware                       */

        pfnct = (PFNCT)VICVectAddr;                  /* Read the interrupt vector from the VIC         */
    }
}


А FIQ хэндлер нужно обрабатывать так, как нужно в конкретном случае и в зависимсоти от того, какая периферия активирует FIQ. То, что приведено - фигня полная.
marfa
Кстати о Микриумовских портах - для AT91RM9200 он тоже нерабочий и именно в этом же месте...
Вот рабочий кусок

void OS_CPU_IRQ_ISR_Handler (void)
{
PFNCT pfnct;
pfnct = (PFNCT)AIC_IRQ_IVR; /* Read the interrupt vector from the AIC */
while (pfnct != (PFNCT)my_AT91F_SpuriousHandler) { /* Handle ALL interrupting devices */

(*pfnct)(); /* Call ISR for interrupting device */
pfnct = (PFNCT)AIC_IRQ_IVR; /* Read the interrupt vector from the AIC */

}
}

Дело в том, что контроллер прерываний при неспровоцированном чтении регистра вектора прерываний контроллер прерываний AT91RM9200 выставляет вектор SpuriousHandler а не 0.....
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.