logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

wywołania funkci w przerwaniach

nigel0 01 Gru 2009 01:53 1446 8
REKLAMA
  • #1 7330578
    nigel0
    Poziom 11  
    Witam wszystkich mam pewien problem z działaniem kodu umieszczonego w w przerwaniach. Sytuacja ta zdarzyła mi się już poraz drugi i nigdzie nie mogę znaleźć żadnych wskazówek jak sobie z tym poradzić. Otoż problem polega na tym, że funkcja która działa bez problemu w pętli głównej, po umieszczeniu jej wywołania w przerwaniu powoduje wykrzaczenie sie programu. Przed przesiadka z CAVR na AVRGCC tego problemu nie zaobserwowałem. Poniżej zamieściłem program z, którym mam mały problem, na potrzeby tematu odpowiednio go spreparowałem tak aby uwidocznić sedno sprawy. Otóż funkcja PRINT(); wysyłająca komunikat na UARTw momencie wprowadzenia dowolnego znaku umieszczona jest przerwaiu SIGNAL(SIG_UART_RECV), zachowuje się dosyć dziwacznie. Jesli argumentem jest string który nie przekracza trzech znaków wszystko jest ok, natomiast jeśli znakow jest wiecej na wyjsciu nie pojawia się nic. Umieszczenie bardziej obszernych fragmentów kodu wydaje się być nie możliwe, czy ktoś z szanownych kolegów spotkał się z podobnym problemem, dodam, że używam biblioteki RKlibAVR.

    
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include <inttypes.h> 
    #include <avr/interrupt.h>
    #include <string.h>
    #include <stdlib.h>
    //#include <avr/eeprom.h>
    
    
    #include "global.h"
    #include "uart.h"
    
    
    prog_char ANSI_NEWLINE[] = {'\n','\r',0}; 
    prog_char ANSI_CLEAR[] = {27,'[','H',27,'[','2','J',0};
    
    #define PRINT(p)	UART_putstr_P(PSTR(p))
    #define CLEAR()		UART_putstr_P(ANSI_CLEAR)
    #define NEWLINE()	UART_putstr_P(ANSI_NEWLINE)
    #define PRINT(p)	UART_putstr_P(PSTR(p))
    
     
    /* ------------------------------------------------------------------------- */
    /* ----------------		 Program glowny 	    ---------------- */
    /* ------------------------------------------------------------------------- */
    
    
    
    SIGNAL(SIG_UART_RECV)
    {
      char c;
      c = _UDR_;              // Get received char
      UART_rbuf[UART_r_in & UART_RMASK] = c;
      UART_r_in++;
      
     
     // PRINT("zzz");        /////////funkcja wykonuje się jest komunikat z uarta
      //PRINT("zzzzzzzz");	///funkcja nie wykonuje, nic nie pojawia się na wyjsciu uarta
    }
    
    
    
    int main(void)
    {    
    	
    
    UART_init();
    
    
    sei();
    
    while(1)
    {
    _delay_ms(1000);
    
    }
    	
    	return;
    }	
  • REKLAMA
  • Pomocny post
    #3 7330711
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #4 7331114
    nigel0
    Poziom 11  
    To wszystko wyjaśnia, a czy stosując INTERRUPT zamiast SIGNAL można doprowadzić do sytuacji w której rozpocznie się wykonywanie przerwania SIG_UART_RECV podczas gdy porzednia instancja jeszcze sie nie zakończyła (pytanie czysto teoretyczne) ?:D
  • Pomocny post
    #5 7331173
    Freddie Chopin
    Specjalista - Mikrokontrolery
    samo ISR zamiast SIGNAL nic nie zmienia, ale ISR można skonfigurować tak, aby odblokowało przerwania na samym początku, więc teoretycznie jest to możliwe.

    4\/3!!
  • #6 7331216
    mirekk36
    Poziom 42  
    nigel0 napisał:
    To wszystko wyjaśnia, a czy stosując INTERRUPT zamiast SIGNAL można doprowadzić do sytuacji w której rozpocznie się wykonywanie przerwania SIG_UART_RECV podczas gdy porzednia instancja jeszcze sie nie zakończyła (pytanie czysto teoretyczne) ?:D


    Tak w ogóle to już od dawna powinieneś używać INTERRUPT zamiast SIGNAL. Ale skoro jesteś na początku drogi i dopiero poznajesz przerwania to dobra rada - na razie daj sobie spokój z możliwością odblokowywania innych przerwań w takcie trwania jednego. To można robić - no ale trzeba mieć już większe doświadczenie i wiedzieć jakie to może nieść skutki - co się będzie działo ze stosem itp itp

    Na razie postaraj się tak jak podpowiedzieli koledzy powyżej tak używać przerwań aby były krótkie tzn krótko się wykonywały - poczytaj sobie o tzw mechaniźmie zastosowania własnych FLAG w przerwaniach a już sporo ci się wyjaśni.

    Później w kolejnych krokach będziesz mógł myśleć o coraz bardziej zaawansowanym korzystaniu z przerwań ;)
  • REKLAMA
  • Pomocny post
    #7 7331608
    tmf
    VIP Zasłużony dla elektroda
    nigel0 napisał:
    To wszystko wyjaśnia, a czy stosując INTERRUPT zamiast SIGNAL można doprowadzić do sytuacji w której rozpocznie się wykonywanie przerwania SIG_UART_RECV podczas gdy porzednia instancja jeszcze sie nie zakończyła (pytanie czysto teoretyczne) ?:D


    To najgorszy pomysl na jaki moglbys w tej chwili wpasc. Odblokowanie przerwan w obsludze przerwan, w przypadku, kiedy ta obsluga jest dluga spowoduje:
    a) mozliwosc przeplnienia stosu i bardzo spektakularne i ciekawe bledy
    b) koniecznosc pisania obslugi przerwania jako funkcji reentrant, co w przypadku wywolywania innych funkcji nie pisanych przez ciebie praktycznie gwarantuje jeszcze ciekawsze sposoby wykrzaczania sie programu.
    Takze podsumowywujac - zrob to co robisz porzadnie, a nie bedziesz musial kombinowac - czyli wszystko co sie da wywal z obslugi przerwania.
  • #8 7333435
    nigel0
    Poziom 11  
    Dzięki wszystkim za entuzjastyczne wypowiedzi, zmieniłem program zgodnie ze wskazówkami i wszystko narazie idzie jak należy. W moim drugim projekcie na AVR(pomiar temp ds1820 wilgotności ds2438 oraz wejść dwustanowych ds2408 oraz powiadomienia sms) dosyć intensywnie korzystam z bibliotek RKlibAVR (LCD I2C->RTC, wiele innych użytecznych funkcji) jednak tak jak w przypadku biblioteki 1-wire tak obecnie z UARTEM mam pewnie problemy otóż po umieszczeniu w głównej pętli cyklicznie odświeżanego tekstu obserwuje nieprawidłowości, screen. Kombinowałem z wielkośćią bufora(włączone przerwania) i w zależności od tego otrzymałem różne efekty jednak za każdym razem wyświetlany tekst rożny był od ideału być może spotkaliscie sie z tą przypadłośćią. Zciągnąłem podobną bibliotekę ze stronki z projektem ds1820 Link analogiczny kod pętli głównej i wszystko chodzi jak marzenie stad mój wniosek, że to jakaś przypadłość kodu biblioteki uarta. Przejrzałem nieco kod tej biblioteki jednak nic nie znalazlem, brak jeszcze obycia i doświadczenia niestety. Poniżej screen z efektem cyklicznego wyświetlania przy włączonym przerwaniu, dodam że gdy nie korzystam z przerwań tekst wyświetlany jest poprawnie. Poniżej zawartość pętli głównej reszta kodu taka sama.


    [img]wywołania funkci w przerwaniach[/img]
    
    while(1)
    {
    _delay_ms(500);
    
    
    	CLEAR();
        PRINT("+ Pomiary");
    	NEWLINE();
    	PRINT("  1.Pokaz sensory");
    	NEWLINE();
    	PRINT("  2.Reguly Alarmowania ");
    	NEWLINE();
    	PRINT("+ Wejscia Dwustanowe");
    	NEWLINE();
    	PRINT("  3.Pokaz Sensory");
    	NEWLINE();
    	PRINT("  4.Reguly Alarmowania");
    	NEWLINE();
    	PRINT("5.Powiadomienia SMS");
    	NEWLINE();
    	PRINT("6.Ustawienia Czasu");
    	NEWLINE();
    	PRINT("Wybierz numer\r\n");
    	
    
    _delay_ms(500);
    
    }
  • REKLAMA
  • Pomocny post
    #9 7333655
    mirekk36
    Poziom 42  
    Jeśli tak będziesz zawsze liczył na te jakieś zassane z netu jakieś tam biblioteki - to jeszcze duuuużo wody w rzece upłynie zanim się skończą twoje problemy które tu opisujesz.

    I tak kiedyś wcześniej czy później (choć lepiej wcześniej) dojdziesz do wniosku, że dokąd sam sobie tych bibliotek po kolei nie zrobisz i to tak od samiuśkiego początku do samego końca, żeby po kolei od podszewki zapoznać się szczegółowo z obsługą każdego modułu procka i nie tylko procka - to zawsze będziesz tracił więcej czasu na doszukiwaniu się błędów w cudzych bibliotekach, na próbowaniu zgrania wielu takich tzw bibliotek razem, na zadawanie pytań o co w tym chodzi itp

    A gwarentuję ci że to nie jest takie trudne i świetnie dasz sobie z tym radę - tylko spokojnie i po kolei ;)
REKLAMA