реклама на сайте
подробности

 
 
> FIQ handler в микриумовском порте ucos под LPC, Че то я не понял.............
Velund
сообщение Apr 12 2006, 14:22
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 693
Регистрация: 19-11-04
Пользователь №: 1 177



Сидел, изучал порт под 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, кстати.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Velund
сообщение Apr 12 2006, 18:39
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 693
Регистрация: 19-11-04
Пользователь №: 1 177



Я про другое... Про FIQ... Там вообще copy/paste с IRQ handler'а, похоже никто даже не вникал в отличия, а уж тем более не пытался запускать... ;-)
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Apr 13 2006, 03:13
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(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. То, что приведено - фигня полная.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 07:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01397 секунд с 7
ELECTRONIX ©2004-2016