Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

At91sam7s, przerwania, procesor się zawiesza.

przesladowana 22 Gru 2006 11:16 1445 3
  • #1 22 Gru 2006 11:16
    przesladowana
    Poziom 12  

    Od niedawna pracuje z ARM (AT91sam7s256) i zatrzymałem się obecnie na etapie uruchomienia FREERTOS. Sam star RTOS poszedł bez problemowo (użyłem dema ze strony http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html) skompilowałem w GCC i wszystko śmiga ładnie pięknie (wątki, tworzenie ,usuwanie ,wstrzymywanie ) .Problem pojawia sie gdy chce użyć przerwań. Niestety procesor się zawiesza. Metodą prób i błędów doszedłem do wniosku ze to robiegówka jest winna. Jej wymiana (na pochodzący z projektu w którym śmigały mi przerwania ) co prawda „ożywia przerwania” ale sam RTOS wisi. Był bym wdzięczny za podesłanie przykładu dla GCC z makefile i wszystkim co potrzebne w którym działa FREERTOS i przerwania.

    0 3
  • #2 22 Gru 2006 18:18
    adamusx
    Poziom 27  

    Pamietaj ze w FreeRTosie przerwan nie mozna obslugiwac w " zwyczajny sposob" tzn funkcjami ktore automatycznie odkladaja dane na stos a potem je zdejmuja itp.

    Nalezy wykorzystac makra portENTER_SWITCHING_ISR() i portEXIT_SWITCHING_ISR

    Przyklad przerwania od timera:

    Inicjalizacja timera

    void timer_init ( void )
    {
    portENTER_CRITICAL();

    //* Open timer0
    AT91F_TC_Open(AT91C_BASE_TC0,TC_CLKS_MCK8,AT91C_ID_TC0);

    //* Open Timer 0 interrupt
    AT91F_AIC_ConfigureIt ( AT91C_ID_TC0, TIMER0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer0_c_irq_handler);
    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC
    // AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC0);
    AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_TC0;

    //* Start timer0
    AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG ;

    portEXIT_CRITICAL();
    //* End
    }

    tu funkcja przerwania

    void timer0_c_irq_handler(void) __attribute__ ((naked));

    void timer0_c_irq_handler(void)
    {
    portENTER_SWITCHING_ISR();

    portBASE_TYPE xSwitchRequired = pdFALSE;
    AT91PS_TC TC_pt = AT91C_BASE_TC0;
    unsigned int dummy;
    //* Acknowledge interrupt status
    dummy = TC_pt->TC_SR;
    //* Suppress warning variable "dummy" was set but never used
    dummy = dummy;
    count_timer0_interrupt++;
    //* Read the output state
    if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOB) & LED1 ) == LED1 )
    {
    AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, LED1 );
    }
    else
    {
    AT91F_PIO_SetOutput( AT91C_BASE_PIOB, LED1 );
    }
    *AT91C_AIC_EOICR = 0 // kasujemy flage przerwania
    portEXIT_SWITCHING_ISR( xSwitchRequired );

    }

    To co zostale pogrubione jest istotne do poprawnego wykorzystania przerwan w FreeRTOS

    pozdrawiam

    0
  • #3 22 Gru 2006 21:57
    przesladowana
    Poziom 12  

    dzieki

    ps. zansz jakies miejsce zwieksza iloscia informacji o rtos niz an ich stronie ???

    0