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

 
 
> проблема - uCos и USART IRQ handler, не могу нормально запустить свой обработчик прерывания в uCos-e
_dem
сообщение Mar 2 2007, 16:14
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Добрый день, уважаемый ALL

Разбираюсь с micrium OS - пожалуйста, ткните носом в страницу мануала.
мозги уже кипят - видимо, чего-то упорно не хотят замечать sad.gif

Проблема в следующем - при попытке навесить свой обработчик прерывания на ком-порт под uCos-ом задача работает до первого вызова OSTimeDlyHMSM(), потом все зависает в цикле OS_TaskIdle().

вот код, запускающий обработчик

Код
    AT91F_AIC_ConfigureIt( AT91C_BASE_AIC,   AT91C_ID_US0, 7 , AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL  | AT91C_AIC_PRIOR_LOWEST, usart0_irq_handler);  
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);


вот сам обработчик

Код
void usart0_irq_handler(void)
{
        // calling irq processor
        if (_comports [ 0 ])
                {
                 _comports [ 0 ] -> __irq_processor();
                }
/////////////////////
    unsigned long rx_data                     = AT91C_BASE_PITC->PITC_PIVR;   /* Read the interrupt source, ignore the value*/

    AT91C_BASE_AIC->AIC_IVR     = 0;                            /* Debug variant of IVR (protect mode is used)*/
    AT91C_BASE_AIC->AIC_ICCR    = AT91C_ID_US0;                 /* Clear  USART0 interrupt                    */
    AT91C_BASE_AIC->AIC_EOICR   = 0;                            /* Signal end of interrupt                    */

       //* Reset the satus bit
AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;  

}


Если убрать вызов
Код
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);

т.е. не включать прерывание в AIC, то все работает - понятно, кроме собственно обработчика.

видимо, ошибся в обработчике, но не могу понять - где ?

----
добавил в обработчик вызовы OSIntEnter() / OSIntExit() - не помогло sad.gif

Сообщение отредактировал _dem - Mar 2 2007, 16:56
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AlexBoy
сообщение Mar 2 2007, 19:55
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Там цепочка вызовов такая: с вектора 0x18 вызввается общий асмовский обработчик OS_CPU_IRQ_ISR_Handler в файле os_cpu_a.s, затем из него общий сишный обработчик, у меня он такой:
Код
void OS_CPU_IRQ_ISR_Handler(void)
  {
    pFNCT pfnct;
  
    pfnct = (pFNCT)*AT91C_AIC_IVR;   // Чтение адреса обработчика с максимальным приоритетом

    AT91C_BASE_AIC->AIC_IVR = 0;                // Debug variant of vector read (protect mode is used)
    if (pfnct) pfnct();                         // Вызвать обработчик
    AT91C_BASE_AIC->AIC_EOICR = 0;              // Признак завершения обработчика
  }


а из него уже обработчик конкретного устройства
Код
void UART0_IRQ_Handler(void)
  {
    BYTE data;
    AT91PS_USART pCOM;
    DWORD status;

    // читаем регистр состояния в соотв. с текущим прерыванием
    status = pCOM->US_CSR;
    
    // Есть принятый байт
    if (status & AT91C_US_RXRDY)
      {
        data = pCOM->US_RHR;
        if (!(status & AT91C_US_FRAME))
          {
            QueueAdd(RxQueue, data);
          }
      }
    ....  

    // timeout приема
    if (status & AT91C_US_TIMEOUT)
      {
       // начать новый отсчет
        pCOM->US_CR = AT91C_US_RETTO;
      }  
      
    // очистить признаки ошибок
    pCOM->US_CR = AT91C_US_RSTSTA;
    // Разбудить задачу
    OSMboxPost(TabloMsg, (void*)1);
  }

Прикрепленные файлы
Прикрепленный файл  os_cpu_a.zip ( 3.61 килобайт ) Кол-во скачиваний: 41
 
Go to the top of the page
 
+Quote Post
_dem
сообщение Mar 5 2007, 11:48
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



с этим я разобрался, спасибо

но все равно не работает sad.gif где может быть собака зарыта ?
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Mar 5 2007, 13:06
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(_dem @ Mar 5 2007, 10:48) *
с этим я разобрался, спасибо

но все равно не работает sad.gif где может быть собака зарыта ?


ну вообще похоже, что прерывания были выключены и не включились обратно
Go to the top of the page
 
+Quote Post
_dem
сообщение Mar 5 2007, 13:13
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Цитата(AlexBoy @ Mar 5 2007, 14:06) *
Цитата(_dem @ Mar 5 2007, 10:48) *

с этим я разобрался, спасибо

но все равно не работает sad.gif где может быть собака зарыта ?


ну вообще похоже, что прерывания были выключены и не включились обратно


ситуация такая, что мой таск работает до тех пор, пока я не передам каким-либо образом управление другому таску - например, задаче IdleTask при вызове функции OSTimeDly()...

обратно управление не передается sad.gif
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Mar 5 2007, 19:08
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(_dem @ Mar 5 2007, 12:13) *
ситуация такая, что мой таск работает до тех пор, пока я не передам каким-либо образом управление другому таску - например, задаче IdleTask при вызове функции OSTimeDly()...

обратно управление не передается sad.gif


Из IdleTask вызов шедулера происходит по прерыванию таймера. Нету прерывания, соответственно остается вечно в IdleTask. Возможно OS_EXIT_CRITICAL где-то забыл.
Go to the top of the page
 
+Quote Post
_dem
сообщение Mar 6 2007, 10:46
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



пока ничего нового sad.gif роюсь в документации и сырцах

сделал 2 своих обработчика прерывания - таймера и usart.
естественно, из обработчика PIT вызываю старый обработчик - чтобы оська работала

включаем свой обработчик таймера - все работает нормально, все переключается
включаем свой обработчик USART - все валится, конкретно - не работает таймер, и, видимо, остальные прерывание тоже не обрабатываются... код одинаковый, за исключением, понятно, констант идентификации периферии ID_US0.

help.gif ! cranky.gif

включаем ISR USART :
Код
void InitUSART (void) {

  // Enable interrupts
  // Disable the interrupt on the interrupt controller
  AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_US0);
  // Save the interrupt handler routine pointer and the interrupt priority
  void * ptr  = 0;
  ptr = (void *)(unsigned long)AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0];
  *(unsigned long *)&old_usart_handlers[0] = (unsigned long)ptr;
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned long) USART0_ISR_Handler;
  // Store the Source Mode Register
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_US0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
  // Clear the interrupt on the interrupt controller
  AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_US0);
  // disable all interrupts on USART
  AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
  // Enable the interrupt on the interrupt controller

  AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_US0);
  // Enable the interrupt on the USART
      return;



}


USART ISR :
Код
static  void  USART0_ISR_Handler (void)
{
    CPU_INT32U      status;

    if (blink) {
        AT91C_BASE_PIOA->PIO_SODR = (1<<13);
        AT91C_BASE_PIOB->PIO_SODR = (1<<26);
    blink = 0;
    }
    else
    {
        AT91C_BASE_PIOA->PIO_CODR = (1<<13);
        AT91C_BASE_PIOB->PIO_CODR = (1<<26);
    blink = 1;
    }
    /*
    status = AT91C_BASE_AIC->AIC_IVR;
    if (status!=0x1124)
        AT91C_BASE_AIC->AIC_IVR = 0;
    
    status = AT91C_BASE_US0->US_CSR;
    if (status==0x1124)
        AT91C_BASE_AIC->AIC_IVR = 0;
*/
    AT91C_BASE_AIC->AIC_ICCR  = 1 << AT91C_ID_US0;                     /* Clear the  interrupts                            */
    AT91C_BASE_AIC->AIC_EOICR = 0;                                      /* Signal end of interrupt                              */
    
    return;    
}

Enable PIT ISR :
Код
AT91C_BASE_PITC->PITC_PIMR =  ((BSP_CPU_ClkFreq() * 1000) / 16 / OS_TICKS_PER_SEC) - 1;


  // Enable interrupts
  // Disable the interrupt on the interrupt controller
  AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_SYS);

  // Save the interrupt handler routine pointer and the interrupt priority
  void * ptr  = 0;
  ptr = (void *)(unsigned long)AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS];
  *(unsigned long *)&old_handler = (unsigned long)ptr;
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned long) pitc_handler;
  // Store the Source Mode Register
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
  // Clear the interrupt on the interrupt controller
  AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_SYS);

  // Enable the interrupt on the interrupt controller
  AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_SYS);

  // Enable the interrupt on the pit
  pimr = AT91C_BASE_PITC->PITC_PIMR;
  AT91C_BASE_PITC->PITC_PIMR = pimr | AT91C_PITC_PITIEN;

  // Enable the pit
  pimr = AT91C_BASE_PITC->PITC_PIMR;
  AT91C_BASE_PITC->PITC_PIMR = pimr | AT91C_PITC_PITEN;


}


PIT ISR :

Код
void pitc_handler(void)
{

for(unsigned short i=0; i<MAX_TIME_COUNTERS; i++)
    {
        if(gMeters[i].connected)
            {
             gMeters[i].counter += OS_TIMER_PERIOD * 2;
            
            // here some like "garbage collector"
            // if no reset within 5 minutes, disconnect that
            if (gMeters[i].counter > 300000)
                gMeters[i].connected = 0;
            }// ?connected
    }// loop

    old_handler();

}



sad.gif хоть не код, ткните хотя бы в страницу мануала ! мозги кипятЪ ! cranky.gif
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Mar 6 2007, 13:26
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



По функциям, то что нужно добавить:
InitUSART:
1. Уарт должен быть настроен (тактовая, pio, скорость)
2. Разрешить прием/передачу AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
3. Включить прерывания в usart AT91C_BASE_US0->US_IER = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE | AT91C_US_FRAME;

USART0_ISR_Handler:
1. Статус должен быть прочитан обязательно. status = AT91C_BASE_US0->US_CSR;
2. Это убрать. AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_US0;
3. Сбросить флаги. AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;

Enable PIT ISR: все нормально

pitc_handler: что-то сильно наворочено, у меня попроще и обязательно нужно прочитать статус иначе не сбросятся прерывания
// ------------------------------------------------------------------------------
// Обработчик системного прерывания (ID_SYS=1)
void SYSIRQ_Handler(void)
{
DWORD status;

status = *AT91C_PITC_PIVR;
if (status & AT91C_PITC_PICNT) // Если системное прерывание от PIT таймера то вызвать OSTimeTick
{
OSTimeTick();
}
}
Go to the top of the page
 
+Quote Post
_dem
сообщение Mar 7 2007, 12:13
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



оно все так и сделано, а OSTick() вызывается в старом обработчике таймера.
мой таймер работает беспроблемно, и переключения тасков происходят, все гуд

а обработчик уарта - нет, хотя тот же код без оськи работает отлично
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- _dem   проблема - uCos и USART IRQ handler   Mar 2 2007, 16:14
- - _dem   проблема решена радикально - переходом на FreeRTOS...   Mar 14 2007, 10:16
- - Tahoe   Такой вопрос назрел. А кто как "дебажится...   Apr 3 2007, 07:55
|- - _dem   Цитата(Tahoe @ Apr 3 2007, 08:55) Такой в...   Apr 3 2007, 09:21
|- - Сергей Борщ   Цитата(Tahoe @ Apr 3 2007, 06:55) А пробл...   Apr 3 2007, 12:28
- - Dron_Gus   Можно еще protected mode использовать для AIC...   Apr 3 2007, 12:28
- - Tahoe   ЦитатаМожно еще protected mode использовать для AI...   Apr 3 2007, 14:27
|- - _dem   Цитата(Tahoe @ Apr 3 2007, 14:27) 2 _dem ...   Apr 5 2007, 18:23
|- - SpiritDance   Цитата(_dem @ Apr 5 2007, 19:23) Порт LwI...   Apr 6 2007, 09:43
- - Tahoe   dem Понятно. Я пока тоже до конца не разобрался с ...   Apr 6 2007, 05:59
|- - Velund   Цитата(Tahoe @ Apr 6 2007, 06:59) Если вк...   Apr 8 2007, 18:41
- - _dem   Цитатапри попытке посмотреть в "хинте" з...   Apr 6 2007, 10:09
- - Tahoe   Цитата(_dem @ Apr 6 2007, 11:09) именно в...   Apr 6 2007, 17:15


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

 


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


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