Pokrewne
menu      Programowanie atmega2560 a atmega128
menu      Program do odczytu kart MMC/CD sektor po sektorze
menu      Niemoznosc zakonczenia programu nagrywania przed czasem w magnetowidzie Samsung
menu      Praca stała (pełny etat) -Programowanie, webmastering, admin
menu      NIOS - programwoanie EPCS z wsadem dla FPGA + kodem dla CPU
menu      Jakaś łatwo programowalna pamięć RÓWNOLEGŁA, nieulotna - co polecicie??
menu      [Oferta] Administracja Serwerami / Monitoring / Tuningowanie / Programowanie
menu      Jak ustawic poczte w programie mail w Mac OS X
menu      Jaki program do puszczania cyklicznych spotów mp3...?
menu      Programik G6 FTP Server. Czy ktoś korzysta?.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • legator.pev.pl
  • Programowanie uC - wspoldzialanie przerwan i algorytmu - zasady sztuki





    Stefcio Z. - 21-02-2007 01:46
    Programowanie uC - wspoldzialanie przerwan i algorytmu - zasady sztuki
      Witam,

    Chciałem spytać Was, nieco bardziej doświadczonych programistów o sposób
    programowania uC, gdy program główny jest dość skomplikowany i zależy od
    wielu sygnałów.
    Dla ustalenia uwagi załóżmy, że uC ma współpracować m.in. z modułem
    radiowym CC1100 (podłączonym przez SPI) oraz niekiedy z modułem Ethernet
    (podłączony do USART) Główne zadania programu to dostęp do medium
    radiowego (a'la CSMA/CA), analiza ramek radiowych (różnych-różnistych -
    zgłoszenia, wiadomości sygnalizacyjne, wiadomości tekstowe, głos) i
    reakcja na nie.

    PODEJŚCIE 1.
    Do tej pory (w innych projektach) robiłem tak:
    1. Procedury obsługi przerwań możliwie najkrótsze (odczyt danych z
    peryferiów, zapis do bufora w pamięci, pobieżna analiza i ustawianie
    flag - np. FRAME_COMPLETE dla programu głównego).
    2. Program główny po stwierdzeniu flagi FRAME_COMPLETE wywoływał funkcję
    Analiza, która ustalała protokół, konkretne znaczenie ramki, ustalając
    kolejne flagi "wyższej warstwy" (np. RECIEVED_CTS), które to flagi brane
    były pod uwagę w głównym programie. Coś w stylu (pseudokod dla wysyłania
    ramki w a'la CSMA/CA):

    [IRQ]
    ....
    Zapisuj bajty do bufora
    if (ostatni bajt) then FRAME_COMPLETE
    ....
    reti

    [MAIN]
    ....
    if (FRAME_COMPLETE) then FrameType = Analiza(bufor);

    if (Stan == RTS_SENT and FrameType == CTS_RECIEVED and ChannelFree) then
    Send(data);
    Stan = DATA_SENT;
    else if (Stan == DATA_SENT and FrameType == ACK_RECIEVED and
    ChannelFree) then
    Stan = IDLE;
    i tu inne skomplikowane przejścia, zwłaszcza gdy np. wystąpią timeouty
    ....

    [Analiza]
    ....
    if (cośtam) then FRAME_TYPE = CTS_RECIEVED;
    ....

    Zaletą jest fakt, że program główny zawsze może zareagować niemal na
    wszystko. Wady - komplikacja warunków (kilka nałożonych na siebie
    diagramów stanów: protokołów będzie kilka, typów ramek ok. 20-30) i
    ogólnie wymięknąłem rozpisując program główny.

    PODEJŚCIE 2.
    Czy nie byłoby grzechem pisanie procedury nadawania ramki po prostu jako
    funkcji:
    [SendFrame]
    Send(RTS);
    WaitFor(CTS_RECIEVED);
    if (Timeout) then return ERROR;
    Send(data);
    WaitFor(ACK_RECIEVED);
    if (Timeout) then return ERROR;
    RETURN OK;

    Zaletą jest klarowny oczekiwany przebieg programu i uproszczenie
    głównego programu. Problemem na pewno są funkcje WaitFor(*), podczas
    których program jest obojętny na wiele innych sygnałów (np. pojawienie
    się ramek innych typów, flagi ustawiane przez procedury innych przerwań
    np. USART). Moim zdaniem można rozważyć w ciele WaitFor sprawdzanie
    niektórych warunków(flag).
    Jakie macie sposoby na programowanie uC obsługujących protokoły,
    muszących brać pod uwagę wiele flag? Dziękuję za wszystkie odpowiedzi,
    wskazówki, uwagi. Mam nadzieję, że nie zamąciłem zbytnio.

    --
    Pozdrawiam,
    Stefcio Z.





    Adam Dybkowski - 21-02-2007 02:46

      Stefcio Z. napisał(a):

    > Dla ustalenia uwagi załóżmy, że uC ma współpracować m.in. z modułem
    > radiowym CC1100 (podłączonym przez SPI) oraz niekiedy z modułem Ethernet
    [...]
    > PODEJŚCIE 1.
    > Do tej pory (w innych projektach) robiłem tak:
    > 1. Procedury obsługi przerwań możliwie najkrótsze (odczyt danych z
    > peryferiów, zapis do bufora w pamięci, pobieżna analiza i ustawianie
    > flag - np. FRAME_COMPLETE dla programu głównego).
    > 2. Program główny po stwierdzeniu flagi FRAME_COMPLETE wywoływał funkcję
    > Analiza, która ustalała protokół, konkretne znaczenie ramki, ustalając
    > kolejne flagi "wyższej warstwy" (np. RECIEVED_CTS), które to flagi brane
    > były pod uwagę w głównym programie. Coś w stylu (pseudokod dla wysyłania
    > ramki w a'la CSMA/CA):

    I to jest najlepsze podejście. Zminimalizuj czas przebywania procesora w
    przerwaniach. Zastosowanie automatu fsm albo nawet kilku do obsługi
    wszystkich protokołów będzie bardzo dobrym i wygodnym rozwiązaniem.
    Pewnie gotowych implementacji jest kilka i masz z czego wybierać, ja
    napisałem po swojemu.
    http://pl.wikipedia.org/wiki/Maszyna...o%C5%84czonych

    --
    Adam Dybkowski
    http://www.amwaw.edu.pl/~adybkows/

    Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.




    Pszemol - 21-02-2007 04:58

      "Adam Dybkowski" <adybkows12@45wp.pl> wrote in message news:erg5bi$1pe$1@atlantis.news.tpi.pl...
    > I to jest najlepsze podejście.

    Niekoniecznie - w większych systemach opłaci się
    zastosowanie jakiegoś systemu operacyjnego, lub
    choćby kernela przełączającego taski i napisanie
    łądnych driverów dla RS232, SPI a program główny
    w kilku zsynchronizowanych muteksami wątkach, itp.




    neuron - 21-02-2007 05:54

     
    > PODEJŚCIE 2.
    > Czy nie byłoby grzechem pisanie procedury nadawania ramki po prostu jako
    > funkcji:
    > [SendFrame]
    > Send(RTS);
    > WaitFor(CTS_RECIEVED);
    > if (Timeout) then return ERROR;
    > Send(data);
    > WaitFor(ACK_RECIEVED);
    > if (Timeout) then return ERROR;
    > RETURN OK;
    >
    > Zaletą jest klarowny oczekiwany przebieg programu i uproszczenie głównego
    > programu. Problemem na pewno są funkcje WaitFor(*), podczas których
    > program jest obojętny na wiele innych sygnałów (np. pojawienie się ramek
    > innych typów, flagi ustawiane przez procedury innych przerwań np. USART).
    > Moim zdaniem można rozważyć w ciele WaitFor sprawdzanie niektórych
    > warunków(flag).

    semafory.

    if semafor= 0 then return
    if semafor= 1 then begin
    SendFrame
    semafor=2
    return
    end

    if semafor = 2 then if cts_received then begin
    send(data)
    semafor:= 3
    end
    if semafor= 3 then if ack_recieved
    itd
    wywolujesz non stop taka funkcje - kiedy wpiszesz jeden w semafor to ruszy.
    nieraz budowalem w ten sposob calkiem pokazne algorytmy

    wojtek
    www.neuron.com.pl
    CMMS Maszyna
    Golem OEE
    Produkt- Baza Wiedzy





    Adam Dybkowski - 22-02-2007 22:45

      Pszemol napisał(a):

    >> I to jest najlepsze podejście.
    >
    > Niekoniecznie - w większych systemach opłaci się
    > zastosowanie jakiegoś systemu operacyjnego, lub
    > choćby kernela przełączającego taski i napisanie
    > łądnych driverów dla RS232, SPI a program główny
    > w kilku zsynchronizowanych muteksami wątkach, itp.

    Oczywiście - co nie zmienia faktu, że w przerwaniach najlepiej przebywać
    jak najkrócej. Jeżeli robisz system czasu rzeczywistego to ważne także
    jest, ile trwa najdłuższe przerwanie o wysokim priorytecie i na jaki
    maksymalny czas blokujesz przerwania w głównym programie.

    --
    Adam Dybkowski
    http://www.amwaw.edu.pl/~adybkows/

    Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.




    Stefcio Z. - 23-02-2007 00:45

      Adam Dybkowski napisał(a):
    > Pszemol napisał(a):
    >
    >>> I to jest najlepsze podejście.
    >>
    >> Niekoniecznie - w większych systemach opłaci się
    >> zastosowanie jakiegoś systemu operacyjnego, lub
    >> choćby kernela przełączającego taski i napisanie
    >> łądnych driverów dla RS232, SPI a program główny
    >> w kilku zsynchronizowanych muteksami wątkach, itp.
    >
    > Oczywiście - co nie zmienia faktu, że w przerwaniach najlepiej przebywać
    > jak najkrócej. Jeżeli robisz system czasu rzeczywistego to ważne także
    > jest, ile trwa najdłuższe przerwanie o wysokim priorytecie i na jaki
    > maksymalny czas blokujesz przerwania w głównym programie.

    Może nie wyraziłem się wystarczająco jasno - jestem całkowicie świadom
    potrzeby maksymalnego skracania obsług przerwań i stosuję tę zasadę zawsze.
    Główne pytanie polega na tym, czy ktoś stosuje zastępowanie
    skomplikowanego diagramu stanów (który w kodzie bez dokumentacji
    graficznej jest w zasadzie nieczytelny) funkcjami działającymi w sposób
    "sekwencyjny" ("czekaj na konkretny sygnał, reaguj na inne
    najistotniejsze sygnały) wg ustalonej w diagramie stanów kolejności -
    tak jak to przedstawiłem w podejściu 2.

    --
    Pozdrawiam,
    Stefcio Z.




    Pszemol - 23-02-2007 00:45

      "Stefcio Z." <stefcioz2@poc_ta.lonet.pl> wrote in message news:erl74p$cii$1@news.onet.pl...
    > Może nie wyraziłem się wystarczająco jasno - jestem całkowicie świadom potrzeby maksymalnego skracania obsług przerwań i stosuję
    > tę zasadę zawsze.
    > Główne pytanie polega na tym, czy ktoś stosuje zastępowanie skomplikowanego diagramu stanów (który w kodzie bez dokumentacji
    > graficznej jest w zasadzie nieczytelny) funkcjami działającymi w sposób "sekwencyjny" ("czekaj na konkretny sygnał, reaguj na inne
    > najistotniejsze sygnały) wg ustalonej w diagramie stanów kolejności - tak jak to przedstawiłem w podejściu 2.

    Gdybys chcial cos takiego napisac w jednym watku to bylby jeden
    wielki balagan w programie obslugujacym kilka rownoleglych funkcji.
    Wez pod uwage ze zdarzenia ze swiata zewnetrznego przychodza
    w stosunku do siebie asynchronicznie.

    Taki sposob pisania kodu jest wlasnie tylko mozliwy dzieki zastosowaniu
    wielowatkowosci. System operacyjny udostepnia Ci bowiem mechanizmy
    synchronizacji miedzywatkami i miedzy funkcjami obslugi przerwan
    (muteksy, semafory, kolejki, flagi zdarzen itp).
    W efekcie mozesz napisac sterownik np. do obslugi portu szeregowego
    i napisac w kodzie glownym:

    -wyslijpaczke(paczka);
    -czekajNaOdpowiedz(2sekundy);
    -przetwarzajodpowiedz();

    A wewnatrz funkcji "wyslij paczke" Twoj watek bedzie spokojnie
    czekal na zasygnalizowanie flagi w obsludze przerwania i to bez
    marnowania czasu procesora gdy wazniejszy watek ma cos do roboty.

    Polecam bardzo dobra ksiazke Labrosse "MicroC/OS-II".
    W zasadzie ksiazka jest o konkretnym mikro-systemie operacyjnym
    ale ma w bardzo latwy/przystepny sposob wyjasniona wielowatkowosc
    i zasady wspolpracy watkow i obslugi przerwan w wiekszych programach.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • konstruktor.keep.pl
  • Design by flankerds.com