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.

Bascom AVR, Atmega16 - Minimalizowanie liczby instrukcji w przerwaniu

MES Mariusz 02 Wrz 2012 20:58 1656 13
  • #1 02 Wrz 2012 20:58
    MES Mariusz
    Poziom 36  

    Witam.

    Z definicji liczba instrukcji w obsłudze przerwania powinna być minimalna, by mogło się ono maksymalnie szybko wykonać.

    Tymczasem w przypadku mojego programu liczba instrukcji w obsłudze przerwania była stosunkowo duża. By wybrnąć z tego problemu zamierzam w przerwaniu ustawić flagę która oznacza, że przerwanie zostało wygenerowane, natomiast w pętli programu głównego wykonać grupę instrukcji tylko raz (po wykonaniu się przerwania) i ustawić flagę na 0. Tym sposobem większość instrukcji znajdzie się w programie głównym a nie w obsłudze przerwania. Proszę o podzielenie się uwagami, czy takie działanie ma sens. Proszę o weryfikację tego rozumowania:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Dodam, że wykonałem test i program który działał poprawnie gdy wszystkie instrukcje zawarte były w obsłudze przerwania, przestał działać, gdy część instrukcji wyniesiona została do programu głównego. Zastanawiam się więc czy takie rozumowanie jest poprawne. Programu niestety w całości zamieścić nie mogę.

    Dziękuję za wypowiedzi w temacie.

    0 13
  • #2 02 Wrz 2012 21:36
    mirekk36
    Poziom 42  

    Tu nie ma pytać czy to ma sens, bo to jest jedynie słuszna droga, a to że ci coś nie działa po przeniesieniu do pętli głównej to już tylko wina programisty czyli twoja.....

    Tym bardziej, że jeśli programując w Bascomie ty chcesz mieć wykonywane operacje co 100us w takim trybie - to życzę powodzenia. Po prostu przyjąłeś totalnie złe założenia a do tego źle je zrealizowałeś (no ale tego to się możemy już tylko domyślać bo nie widać kodu, który przeniosłeś)

    za to zdecydowanie NA PEWNO - dobrą drogę wybrałeś ;) z tą flagą - przecież średnio w co drugim poście również na elektrodzie jest mowa o takim sposobie jako PODSTAWIE działania.

    0
  • #3 02 Wrz 2012 21:38
    tmf
    Moderator Mikrokontrolery Projektowanie

    Niespecjalnie twój pomysł ma sens. A raczej nie do końca ma sens. Spowoduje on tylko zmniejszenie latencji obsługi innych przerwań, ale to samo możesz uzyskać pisząc przerwania nieblokujące (o ile Bascom to umożliwia). Pomysł z flagą ma sens w sytuacji w której obsługa przerwania byłaby koszmarnie długa, ale nie z powodu złożoności obliczeniowej, a jedynie czekania na jakieś zdarzenie. Natomiast kryje się tu poważny problem - załóżmy, że obsługa przerwania trwa dłużej niż czas pomiędzy kolejnymi przerwaniami. Co wtedy? Ano przerwania są gubione i całość działa tak sobie. Inna sprawa - twoja flaga musi być volatile, nie mam pojęcia jak w Bascomie to się realizuje, ale musisz mu zasygnalizować, że zmienna może się zmieniać w sposób nie wynikajacy z sekwencji programu.

    0
  • #4 02 Wrz 2012 21:44
    mickpr
    Poziom 39  

    MES Mariusz napisał:
    Dim Wygenerowano_przerwanie$ As Bit

    Nie wiem jak wygląda implementacja bitu w Bascomie, ale założę się, że jest wolniejsza niż użycie zwykłego bajtu.

    Co do sposobu z flagą, to jest on jak najbardziej poprawny.
    Tworzysz pewnego rodzaju "semafor", który wykorzystujesz w programie głównym.
    Jednak jeśli wykonanie operacji w pętli głównej przerwania, której konieczność sobie "zaflagowagowałeś" (przy okazji wystąpienia przerwania) zajmuje więcej czasu niż przerwanie, to musisz zrezygnować z kilku kolejnych przerwań.

    Czytaj: w przerwaniu zmieniasz flagę na ustawioną tylko wtedy, gdy była wyzerowana.
    W przeciwnym razie po prostu opuszczasz przerwanie (jakby go nie było).

    0
  • #5 02 Wrz 2012 21:47
    LordBlick
    VIP Zasłużony dla elektroda

    No cóż, Bascom umożliwia wstawki w asemblerze, co może skrócić obsługę przerwania...

    0
  • #6 02 Wrz 2012 21:59
    tmf
    Moderator Mikrokontrolery Projektowanie

    mickpr napisał:

    Co do sposobu z flagą, to jest on jak najbardziej poprawny.
    Tworzysz pewnego rodzaju "semafor", który wykorzystujesz w programie głównym.


    Poprawny to on jest - semantycznie :) Zastanów się jaka jest różnica pomiędzy obsługą całości w przerwaniu, a obsługą całości poza przerwaniem. Będę wdzięczny za wskazanie :)

    0
  • #7 02 Wrz 2012 22:04
    mickpr
    Poziom 39  

    tmf napisał:
    Zastanów się jaka jest różnica pomiędzy obsługą całości w przerwaniu, a obsługą całości poza przerwaniem. Będę wdzięczny za wskazanie

    Już mówię. W przerwaniu oprócz ustawiania flagi można robić oczywiście coś dodatkowo.
    Wtedy różnica już chyba jest, prawda?

    Przykładowo : masz przerwanie timera, które wykonuje 2 funkcje:
    - Przełącza multipleksowane wyświetlacze.
    - wysyła co X przerwań zawartość bufora przez RS.
    Pierwsze zadanie musi się wykonywać stale.
    Drugie zadanie może trwać i trwać - nie zakłócając pracy pierwszemu (multipleksowaniu wyświetlacza).
    Dobrze mówię?
    Pierwsze wykonujemy w przerwaniu, drugie - w kodzie głównym.

    0
  • #8 02 Wrz 2012 22:11
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tak, lecz jest to sytuacja, którą opisałem w poście #3. Z drugiej strony, ja bym przedstawiony przez ciebie problem rozwiązał inaczej - w dwóch przerwaniach. W przedstawionej sytuacji wysyłkę można zrobić całkowicie w oparciu o przerwania USART, a timer niech robi to do czego służy :) A jakieś inne różnice?

    0
  • #9 02 Wrz 2012 22:28
    mickpr
    Poziom 39  

    O jaką różnicę koledze chodzi?.
    O fakt, że dla zwykłych (blokujących inne przerwania) przerwań wykonanie instrukcji w kodzie przerwania, a wykonanie ich w pętli głównej na podstawie ustawionej flagi to praktycznie to samo?.
    Czy o coś innego?

    tmf napisał:
    Z drugiej strony, ja bym przedstawiony przez ciebie problem rozwiązał inaczej - w dwóch przerwaniach.

    Pewnie że można w 2 przerwaniach, ale jak timerów jest za mało - to można stosować takie tricki.

    0
  • #10 03 Wrz 2012 09:24
    tmf
    Moderator Mikrokontrolery Projektowanie

    mickpr napisał:
    O jaką różnicę koledze chodzi?.
    O fakt, że dla zwykłych (blokujących inne przerwania) przerwań wykonanie instrukcji w kodzie przerwania, a wykonanie ich w pętli głównej na podstawie ustawionej flagi to praktycznie to samo?.


    Mniej więcej właśnie o to. Tak czy siak mamy niepodzielny fragment kodu blokujący inne "procesy". Co innego gdyby to rozbić na małe fragmenty sekwencyjnie wywoływane, pomiędzy którymi znajdzie się miejsce na realizację innych zadań. Tyle, że to już wywraca do góry nogami całą filozofię programowania sekwencyjnego.

    mickpr napisał:
    tmf napisał:
    Z drugiej strony, ja bym przedstawiony przez ciebie problem rozwiązał inaczej - w dwóch przerwaniach.

    Pewnie że można w 2 przerwaniach, ale jak timerów jest za mało - to można stosować takie tricki.


    W twoim przykładzie nie potrzebuję dwóch timerów, tylko timera (multipleksowanie) + przerwanie USART, które jest wolne.

    0
  • #11 03 Wrz 2012 09:30
    mickpr
    Poziom 39  

    tmf napisał:
    Co innego gdyby to rozbić na małe fragmenty sekwencyjnie wywoływane, pomiędzy którymi znajdzie się miejsce na realizację innych zadań. Tyle, że to już wywraca do góry nogami całą filozofię programowania sekwencyjnego.

    To już zahacza o wielowątkowość.
    Ze swojej strony - np. taki FreeRTOS jest fajną zabawką, ale niestety czasem narzut (zużycia RAM, nie wspominając nawet o pozostałych zasobach) jaki daje jest zbyt duży.

    tmf napisał:
    W twoim przykładzie nie potrzebuję dwóch timerów, tylko timera (multipleksowanie) + przerwanie USART, które jest wolne.
    Przykład z UARTem nie był fortunny, powiedzmy że zamiast niego mamy "czarną skrzynkę" z dość długim czasem wykonywania.

    0
  • #12 03 Wrz 2012 11:35
    SylwekK
    Poziom 29  

    Niestety nie znam algorytmu, który ma być realizowany ale z doświadczenia wiem, że KAŻDY problem ma co najmniej dwa rozwiązania i zamiast wykonywać wszystkie instrukcje w jednym przerwaniu może wystarczyło by je rozbić na sekwencje...
    Znacznik z przerwania dla kodu w pętli głównej ma sens tylko w przypadku gdy ramy czasowe są elastyczne i nie ma obowiązku wykonania kodu co każde przerwanie - bo to więcej niż pewne, że w końcu któryś impuls przepadnie...

    0
  • #13 03 Wrz 2012 13:01
    tmf
    Moderator Mikrokontrolery Projektowanie

    mickpr napisał:
    tmf napisał:
    Co innego gdyby to rozbić na małe fragmenty sekwencyjnie wywoływane, pomiędzy którymi znajdzie się miejsce na realizację innych zadań. Tyle, że to już wywraca do góry nogami całą filozofię programowania sekwencyjnego.

    To już zahacza o wielowątkowość.
    Ze swojej strony - np. taki FreeRTOS jest fajną zabawką, ale niestety czasem narzut (zużycia RAM, nie wspominając nawet o pozostałych zasobach) jaki daje jest zbyt duży.


    Owszem, ale zauważ, że obsługa przerwań to już coś w rodzaju wielowątkowości właśnie. Tylko realizowanej bardzo naturalnie, tak naturalnie, że wiele osób zapomina, że handler przerwania to właściwie osobny wątek ze wszystkimi tego konsekwencjami. Teraz przeniesienie tego do kodu "głównego" tak jak padła propozycja z flagą, powoduje, że żeby to miało jakiś sens tą mini-wielowątkowość trzeba zaimplementować w kodzie głównym. Jeśli jej nie zaimplementujemy to nic nam ta flaga nie da, a wręcz skomplikuje cały kod zupełnie niepotrzebnie.

    mickpr napisał:
    tmf napisał:
    W twoim przykładzie nie potrzebuję dwóch timerów, tylko timera (multipleksowanie) + przerwanie USART, które jest wolne.
    Przykład z UARTem nie był fortunny, powiedzmy że zamiast niego mamy "czarną skrzynkę" z dość długim czasem wykonywania.


    Dyskusja o czarnych skrzynkach jest małokonstruktywna :)
    Oczywiście na siłę da się znaleźć zalety pomysłu z flagą, ale nie jest to tak jak ktoś powyżej przedstawiał, że to doskonały pomysł. Bo IMHO w 99% przypadków to marny pomysł :) Ten 1% to black boxy :)

    0
  • #14 04 Wrz 2012 19:47
    30402
    Użytkownik usunął konto