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

 
 
 
Reply to this topicStart new topic
> FIQ у AT91RM9200, uCOS 2.84, IAR 4.41
Bitman
сообщение Apr 8 2008, 12:25
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 25-01-08
Пользователь №: 34 422



Никак не получается нормально запустить FIQ.

плата на AT91RM9200, ось uCOS 2.84 с портом ARM 1.81, компилер IAR 4.41

Кусочки стартапа, которые я и не менял, вроде работают штатно:

Код
    org  0x00
__program_start
    b  ?start
    b  ?OS_CPU_ARM_ExceptUndefInstrHndlr
    b  ?OS_CPU_ARM_ExceptSwiHndlr
    b  ?OS_CPU_ARM_ExceptPrefetchAbortHndlr
    b  ?OS_CPU_ARM_ExceptDataAbortHndlr
    b  ?OS_CPU_ARM_ExceptAddrAbortHndlr
    b  ?OS_CPU_ARM_ExceptIrqHndlr
    b  ?OS_CPU_ARM_ExceptFiqHndlr

?OS_CPU_ARM_ExceptResetHndlr
    b  OS_CPU_ARM_ExceptResetHndlr

?OS_CPU_ARM_ExceptUndefInstrHndlr
    b  OS_CPU_ARM_ExceptUndefInstrHndlr

?OS_CPU_ARM_ExceptSwiHndlr
    b  OS_CPU_ARM_ExceptSwiHndlr

?OS_CPU_ARM_ExceptPrefetchAbortHndlr
    b  OS_CPU_ARM_ExceptPrefetchAbortHndlr

?OS_CPU_ARM_ExceptDataAbortHndlr
    b  OS_CPU_ARM_ExceptDataAbortHndlr

?OS_CPU_ARM_ExceptAddrAbortHndlr
    b  OS_CPU_ARM_ExceptAddrAbortHndlr

?OS_CPU_ARM_ExceptIrqHndlr
    b  OS_CPU_ARM_ExceptIrqHndlr

?OS_CPU_ARM_ExceptFiqHndlr
    b  OS_CPU_ARM_ExceptFiqHndlr


в файле os_cpu_a.asm:

Код
;*******************************************************************************
*************************
;                                  INTERRUPT REQUEST EXCEPTION HANDLER
;*******************************************************************************
*************************

OS_CPU_ARM_ExceptIrqHndlr
    SUB     LR, LR, #4                                         ; LR offset to return from this exception: -4
    STMFD   SP!, {R0-R12, LR}                                  ; Push working registers
    MOV     R3, LR                                             ; Save link register
    MOV     R0, #OS_CPU_ARM_EXCEPT_IRQ                         ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ
    B            OS_CPU_ARM_ExceptHndlr                        ; Branch to global exception handler


;*******************************************************************************
*************************
;                               FAST INTERRUPT REQUEST EXCEPTION HANDLER
;*******************************************************************************
*************************

OS_CPU_ARM_ExceptFiqHndlr
    SUB     LR, LR, #4                                         ; LR offset to return from this exception: -4
    STMFD   SP!, {R0-R12, LR}                                  ; Push working registers
    MOV     R3, LR                                             ; Save link register
    MOV     R0, #OS_CPU_ARM_EXCEPT_FIQ                         ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ
    B            OS_CPU_ARM_ExceptHndlr                        ; Branch to global exception handler



;*******************************************************************************
*************************
;                                       GLOBAL EXCEPTION HANDLER
;*******************************************************************************
*************************

OS_CPU_ARM_ExceptHndlr
    MRS     R1, SPSR                                           ; Save CPSR (i.e. exception's SPSR)

                                                               ; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION
                                                               ;   SPSR.Mode = FIQ, IRQ, SVC, ABT, UND : Other exception
                                                               ;   SPSR.Mode = SYS                     : Task
                                                               ;   SPSR.Mode = USR                     : *unsupported state*
    AND     R2, R1, #OS_CPU_ARM_MODE_MASK
    CMP     R2,     #OS_CPU_ARM_MODE_SYS
    BNE     OS_CPU_ARM_ExceptHndlr_BreakExcept

и далее по тексту.

В результате попадаем уже в C-ную функцию - обработчик:
Код
void  OS_CPU_ExceptHndlr (CPU_DATA  except_id) {
  BSP_FNCT_PTR   pfnct;
  CPU_INT32U    *sp;


  if (except_id ==  OS_CPU_ARM_EXCEPT_FIQ) {
    pfnct   = (BSP_FNCT_PTR)*AT91C_AIC_FVR;                 //  Read the interrupt vector from the AIC.              
    *AT91C_AIC_FVR=0;                                       // Protected mode
    if (pfnct  != (BSP_FNCT_PTR)0) {                        //  Make sure we don't have a NULL pointer.              
      (*pfnct)();                                           //  Execute the ISR for the interrupting device.        
    }
  }
  else {
    if (except_id ==  OS_CPU_ARM_EXCEPT_IRQ) {
      pfnct   = (BSP_FNCT_PTR)*AT91C_AIC_IVR;             //  Read the interrupt vector from the AIC.              
      *AT91C_AIC_IVR=0;
      if (pfnct  != (BSP_FNCT_PTR)0) {                        //  Make sure we don't have a NULL pointer.              
        (*pfnct)();                                           //  Execute the ISR for the interrupting device.        
      }
    } else {

      ... тут вырезан вывод в dbgu инфы об исключении ...
                                                                // Infinite loop on other exceptions.                  
                                                                // Should be replaced by other behavior (reboot, etc.)  
      while (DEF_TRUE) {
         ;
      }
    }
  }
}


Эту функцию пришлось переделать, т.к. она не читала AIC_FVR для FIQ, а было написано чтение AIC_IVR в любом варианте, что для FIQ не работало. Сейчас вызывается обработчик, который мы записали в AIC_SVR[0], сам этот обработчик вот такой:

Код
void  FIQ_Handler (void) {
  FIQ_counter++;
}


В EOICR не записываю ничего, т.к. FIQ настроен на фронт и автоматичекси сбрасывается при чтении AIC_FVR. Хотя и писать пробовал тоже, результат одинаков.

В принципе, все работает ... но недолго. Запускаю прогу, беру проводочек и начинаю FIQ вход им коротить на землю. В результате на один 'коротыш' выскакивает от нескольких, до сотни прерываний из за дребезга. И может насчитать несколько тысяч но, в какой-то прекрасный момент, процессор проваливается в data abort. После долгих колупаний удалось выяснить, что в функции OS_SchedNew переменная OSPrioHighRdy получает значение 56 (десятичное). С какого перепугу я так и не понял, а такой задачи у меня нет, т.е. TCB у неё нулевой. При попытке сшедулится на эту задачу операционка воспринимает начало памяти с 0 адреса как TCB, грузит в R13 вместо адреса стека команду перехода и, в результате попытки чтения из стека, из адреса 0xEA...... происходит data abort.
Если FIQ не тыкать - всё работает долго и стабильно. Может кто сталкивался с подобной проблемой? Или есть работающий пример с FIQ под uCOS и IAR? Ну или хоть какой, где FIQ и IRQ работают в параллель? А то уже блин и идей нет, как это можно отыскать sad.gif
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Apr 8 2008, 20:46
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Первый вариант - проверяйте стеки.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 8 2008, 21:14
Сообщение #3


Гуру
******

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



Цитата(Bitman @ Apr 8 2008, 16:25) *
Запускаю прогу, беру проводочек и начинаю FIQ вход им коротить на землю. В результате на один 'коротыш' выскакивает от нескольких, до сотни прерываний из за дребезга.

Проводочек, руками... Несколько стремный способ проверки, Вам не кажется?

Да и какой смысл использовать FIQ при таком количестве требухи в обработчиках?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Apr 9 2008, 05:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aaarrr @ Apr 8 2008, 23:14) *
Да и какой смысл использовать FIQ при таком количестве требухи в обработчиках?

Да уж..навалено "требухи" немеряно. Даже читать не хочется. Конечно, этот замес можно вычититать, выправить, но сам подход к делу - сделать из FIQ то-же самое,что и IRQ неправилен. FIQ обработчик разумно смотрится простым, без завязки на систему (не вызывающий системных сервисов типа переключения контекста ) и по этой причине не требующий никаких дополнительных наворотов вообще.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Bitman
сообщение Apr 9 2008, 06:15
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 25-01-08
Пользователь №: 34 422



Я пока новичок в этом деле, прошу сильно не ругать smile.gif
Ладно, бог с ним с FIQ, видимо он мне и не нужен, это я погорячился. Переключился на IRQ0.
Эффект остался прежним.

Это не Spurious Interrupt, повесил на это дело обработчик, в него не заходит.

Стеки все сделал большими, не помогло. Момент возникновения ошибки не изменился. Сразу после abort проверил все стеки, у всех вверху нули, т.е. они не переполнялись. Может есть ещё способ как их проверить?

Продолжаю эксперименты ... может есть у кого идеи как отловить это в динамике? В статике всё отлично, когда прохожу в отладчике по шагам от момента возникновения прерывания до его завершения, никаких аномалий не вижу. На выходе стеки такие-же, как и на входе, вычищаются верно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 9 2008, 06:21
Сообщение #6


Гуру
******

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



Для начала я бы источник подачи прерывания автоматизировал, а потом уже разбирался с глюками. Можно, например, выход таймера на IRQ бросить. Просто есть подозрение, что железка у Вас дуреет.
Go to the top of the page
 
+Quote Post
Bitman
сообщение Apr 9 2008, 08:53
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 25-01-08
Пользователь №: 34 422



Цитата(aaarrr @ Apr 9 2008, 10:21) *
Для начала я бы источник подачи прерывания автоматизировал, а потом уже разбирался с глюками. Можно, например, выход таймера на IRQ бросить. Просто есть подозрение, что железка у Вас дуреет.


Так и есть! Вот ведь кто бы мог подумать?! Подал 30КГц c таймера - работает и не жужжит. Отсюда делаем вывод, что железке на прерывание нельзя подавать фигню всякую, наверняка есть некоторая предельная частота, выше которой железка дуреет.

Всем спасибо за помощь и идеи! будем двигаться дальше smile.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 9 2008, 09:01
Сообщение #8


Гуру
******

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



Цитата(Bitman @ Apr 9 2008, 12:53) *
Отсюда делаем вывод, что железке на прерывание нельзя подавать фигню всякую, наверняка есть некоторая предельная частота, выше которой железка дуреет.

ИМХО, дело не в частоте, а в проводе. Ну да ладно.
Go to the top of the page
 
+Quote Post
Bitman
сообщение Apr 9 2008, 09:16
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 25-01-08
Пользователь №: 34 422



Цитата(aaarrr @ Apr 9 2008, 13:01) *
ИМХО, дело не в частоте, а в проводе. Ну да ладно.


Век живи, век учись smile.gif Ещё раз спасибо!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:46
Рейтинг@Mail.ru


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