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

PIC ala wielowątkowość. Domykanie szyb. PIC 16f628a.

Snake71 26 Wrz 2010 23:11 3683 26
  • #1 26 Wrz 2010 23:11
    Snake71
    Poziom 11  

    Witam, opracowuję program na pic 16f628a który usprawni moją elektrykę szyb w samochodzie, mianowicie chodzi o domykanie po zamknięciu auta, a także o zamykanie / otwieranie po dłuższym naciśnięciu przycisku. Problem polega na tym że szyba lewa będąc zamykaną może przesatać być zamykaną, bądź szyba prawa może zostać być otwieraną, itd, itd. Rozdzielając pracę mikroprocesora na 2 części, czyli szyba lewa, szyba prawa, nie będzie problemu, poradzę sobie. Mogę to zrobić na 2 x PIC12FXXX 8 nóżkowym ( jeden szyba lewa, a drugi szyba prawa ) , ale ciekawość ludzka nie zna granic :) Jak Wy poradzilibyście sobie z takim problemem?

    0 26
  • CControls
  • #2 26 Wrz 2010 23:24
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jedynym "problemem" jest to, że źle napisałeś program, czyli masz pewnie pętle z czekaniem do oporu, a wtedy nie dziwne, że układ potrafi robić tylko jedno.

    Należy wykorzystać filozofię zdarzeń (events), rozdzielając wszystko na jak najdrobniejsze elementy, tak aby ich wykonywanie było maksymalnie krótkie i nie wymagało praktycznie żadnego oczekiwania. Przykładowe zdarzenia: rozpocznij zamykanie szyby - włącz, czas minął - wyłącz silnik, przeciążenie - wyłącz silnik, zakończ zamykanie szyby - wyłącz silnik, ...

    4\/3!!

    0
  • #3 27 Wrz 2010 09:54
    Snake71
    Poziom 11  

    Jeszcze programu nie napisałem, tylko jak na obecną chwilę zajmuję się samą problematyką, a na taki pomysł jak piszesz jeszcze nie wpadłem. Dzięki za podpowiedź. Pozdrawiam.

    0
  • CControls
  • #4 27 Wrz 2010 10:32
    betoven
    Poziom 12  

    Dodaj tylko do wypowiedzi kolegi, że takie rozwiązanie sprawdza się świetnie, gdy obsługę jednego z timerów wykorzystamy do ich wywołać, pod pewnymi warunkami. Te warunki sprawdzają czy zdarzenie nastąpiło czy tez nie. Jeśli tak to wywołujemy odpowiadającą zdarzeniu procedurkę. Jest to o tyle wygodne, że w procedurce nie musisz się martwić o sprawdzenie czy powinna ona być uruchomiona, a główna pętla programu pozostaje pusta, lub może wykonywać inne czynności.

    0
  • #5 27 Wrz 2010 12:27
    Urgon
    Poziom 36  

    AVE...

    Jest kilka projektów i co najmniej dwa systemy/języki programowania(z czego jeden darmowy), gdzie masz wielozadaniowość. Spotkałem się z dwoma rozwiązaniami:
    1. Pętla główna sprawdza stan zadań i stan przerwań i wywołuje odpowiednie zadania, które mogą być aktywne, uśpione, zakończone lub oczekujące uwagi. Zadania pracują póki nie zmienią stanu lub nie nastąpi przerwanie.
    2. Zadania współdzielą czas procesora po równo lub wg. priorytetów. Jest to najbliższe tradycyjnym systemom operacyjnym.

    Jak ja bym to zrobił?
    Pętla główna z pomocą ADC mierzy obciążenie silników szyb. Stan przycisków i silnika sprawdza się i obsługuje z pomocą przerwań. W razie wciśnięcia przycisku skok do bloku programu, który sprawdza czas przyciśnięcia i przekierowuje do któregoś z pozostałych bloków(otwórz lewą szybę, otwórz prawą, zamknij lewą, zamknij prawą). Te zmieniają tylko stan odpowiednich wyjść sterujących. Zanik pracy silnika włącza zamykanie obu szyb. Pracę kończy wykrycie przeciążenia silników...

    0
  • #6 27 Wrz 2010 13:44
    nsvinc
    Poziom 35  

    Mozna to tez zbudować na flagach <- teoria algorytmu opartego na zdarzeniach. W wiekszych systemach do obslugi zdarzen stosuje sie FIFO, do ktorego dane wrzuca producent zbierający dane z wejsc, touchpanela, innych peryferiow, z tego FIFO dane wyciaga konsument, ktory decyduje co robic z tymi zdarzeniami...

    Nie jest jasne jak mierzyć czas wcisniecia - przecież nie pętlą ktora inkremenuje licznik i czeka na puszczenie typu while(wcisniety)....
    Tak sie nie robi i nie wolno robić - wcisniety przycisk spowoduje zwieche
    programu i w efekcie zjaranie silnikow!

    Do liczenia czasu wcisku nalezy wykorzystac timer, ktory na zewn. przerwanie zostanie odpalony i na kolejne przerwanie zatrzymany. Przerwanie musi chodzic na oba zbocza. W ifie ktory sprawdzi puszczenie, ustawiac flage, i zresetowac timer.

    W glownej petli sprawdzac flage, i jesli jest ustawiona, to wtedy wykonac jakis kod (np. ten o ktorym napisał Urgon ), a nastepnie zgasic flage.

    0
  • #7 27 Wrz 2010 15:27
    Urgon
    Poziom 36  

    AVE...

    @Nsvinc...
    Zrobiłbym to tak(na PIC16F785):
    1. Ustaw przerwanie pinu na zbocze narastające.
    2. Gdy pojawi się zbocze narastające:
    - zresetuj flagę przerwania;
    - ustaw przerwanie pinu na zbocze opadające;
    - ustaw preskaler timera;
    - włącz timer sprzężony z głównym zegarem.
    3. Gdy pojawi się zbocze opadające:
    - zatrzymaj timer;
    - zresetuj flagę przerwania;
    - sprawdź wartość licznika timera i porównaj z żądaną wartością(ustaw flagę dla żądanego zadania);
    - wróć do punktu pierwszego.
    Między punktami jest czas dla innych zadań, bo całość opiera się na przerwaniach. Tak to jest rozwiązane w tym przypadku, bo ten PIC nie ma zewnętrznego pinu włączającego timer zboczami...
    Jeszcze jedno: ten PIC ma tylko jeden pin sterowany zboczami, więc przy okazji trza zrobić to sprzętowo tak, by go sterował każdy przycisk, a przy tym, by poszczególne przyciski sterowały innymi pinami. Sprawdzanie, który przycisk został wciśnięty można zrealizować w punkcie drugim...

    0
  • #8 27 Wrz 2010 20:46
    janbernat
    Poziom 38  

    Zewnętrznego przerwania szkoda- bo może sie przydać na coś naprawdę ważnego- jakiś alarm czy coś.
    Uruchamianie i zatrzymywanie timera oznacza że obsłuży tylko jeden proces (podprogram) czy jak go zwał.
    Można to zrobić tak aby jeden Timer "cykał" stale i ustawiał kilka flag co jeden "cyk"- i wystawiał przerwanie- najlepiej CTC.
    Jego czas trwania należy ustawić tak aby starczyło do obsługi najkrótszych zdarzeń zewnętrznych.
    A w głownej pętli robimy kilka"bloków".
    W każdym z nich sprawdzamy czy zaszło jakieś zdarzenie i czy odpowiednia flaga z timera ustawiona.
    Kasujemy odpowiednią flagę, inkrementujemy jakąś zmienną- w każdym bloku inną flagę i inną zmienną.
    Gdy zmienna osiągnie ustawioną uprzednio wartość to wykonujemy to co w danym bloku było do zrobienia.
    Co oczywiście nie zwalnia z pilnowania czasów.

    0
  • #10 27 Wrz 2010 21:09
    janbernat
    Poziom 38  

    Ale Timerów to tyle pewnie nie ma...

    0
  • #12 27 Wrz 2010 22:32
    sedr
    Poziom 17  

    Urgon napisał:
    AVE...

    Jest kilka projektów i co najmniej dwa systemy/języki programowania(z czego jeden darmowy), gdzie masz wielozadaniowość.


    Mógłbyś wyklarować?

    0
  • #13 27 Wrz 2010 23:05
    nsvinc
    Poziom 35  

    Co tu klarowac? wielozadaniowosc nalezy napisac sobie samemu - w szczegolnosci na mikrokontrolery!

    ->janbernat
    Szkoda? Przeciez po to one sa! Skoro szkoda Ci ext int na przycisk, to do czego chciałbys tego uzyc? Po co pisac programowe algorytmy do realizacji czegos, co zalatwi hardware?...

    ->Urgon
    OK algorytm jest jak najbardziej OK, ale mam zastrzezenia....
    1. Po co zmieniac w ISR preskaler timera? Przeciez mozna go ustawic na stale w initach, a potem nie dotykac
    2. IFa dotyczacego czasu nacisniecia nie pisalbym w przerwaniu, a w superloopie. Przerwanie powinno trwac jak najkrocej. Ale to tylko taki niuans
    3. Jesli PIC dysponuje przerwaniami na LOWLEVEL to az sie prosi odpalac timer w przerwaniu ext int, a potem w timerze (z odpowiednio skroconym cyklem) sprawdzac stan pina - w efekcie na jedno wyjdzie oprocz znacznie zmniejszonego obciazenia procesora....Po Twojemu jest po prostu wiecej roboty.
    Na codzien piszę na ARMy, ale i tak optymalizuje algorytmy tak zeby nie zarżnąć procesora głupimi procesami (kiedys o tym pisał Chopin) bo moc obliczeniowa powinno sie wykorzystywać do konkretnego celu a nie do usprawiedliwiania lipnych algorytmow[/b] :)

    0
  • #14 27 Wrz 2010 23:09
    Urgon
    Poziom 36  

    AVE...

    Ad. 1. Faktycznie, masz rację.
    Ad. 2. Wystarczy w przerwaniu tylko skopiować stan licznika do zmiennej, a resztę faktycznie zrobić w pętli głównej.
    Ad. 3. Po co sprawdzać stan pinu, skoro dostaniesz przerwanie po pojawieniu się drugiego zbocza? Timer będzie sobie sam cykał cierpliwie nie zabierając Ci czasu procesora...
    Przy zegarze wewnętrznym 4Mhz i tak masz dość czasu, by wszystko zrobić nim timer skończy odliczać czas przyciśnięcia przycisku. Jeśli jednak chcesz wykorzystać licznik timera i przerwanie przy przepełnieniu, to trza ustawić zarówno preskaler, jak i stan początkowy licznika. Kod inicjalizacji jest dłuższy...

    Jeszcze jedno:
    Kilka dialektów C udostępnia elementy potrzebne do zrobienia systemu wielozadaniowego. Ale minimum to zazwyczaj PIC18Fxxx, bo mniejsze są po prostu za małe...

    0
  • #15 27 Wrz 2010 23:46
    sedr
    Poziom 17  

    nsvinc napisał:
    Co tu klarowac? wielozadaniowosc nalezy napisac sobie samemu - w szczegolnosci na mikrokontrolery!


    Chodzi o to, jakie języki wspierają wielozadaniowość? Z tego co wiem to z bardziej znanych języków Ada i Java mają wielozadaniowość jako część języka, ale tych na takich małych uC próżno szukać (chociaż jest GNAT dla AVRów :) ). :P

    A co do multithreadingu to na małe uC nie ma sensu go wykorzystywać, lepsza jest pętla zdarzeń.

    0
  • #16 28 Wrz 2010 04:15
    nsvinc
    Poziom 35  

    Rzeczywisty multithreading na kilkumipsowych mikrokontrlerach to samobójstwo. Przy tych kilku mipsach czas rdzenia zajmowany przez nawet najprostszy scheduler bedzie rzedu 30%...!
    Na slabe procki pisze sie superloopy i wykorzystuje jak najintensywniej przerwania. Bez tego te procki tak naprawdę nic nie potrafią. Nawet 8086 z zegarem 4.77MHz jest wydajniejszy niż jakieś PICki 16F lub 18F. Nawet pisanie kodu w C optymalizuje się na poziomie samego C pod rdzen!!

    0
  • #17 28 Wrz 2010 09:24
    Urgon
    Poziom 36  

    AVE...

    8086 jest wydajniejszy, bo ma architekturę CISC i jest procesorem 16-bitowym. A mikrokontrolery w architekturze RISC z zasady nie mają tak przydatnych funkcji, jak DMA i wiele trybów adresowania, zaś bez tego wydajność jest mocno ograniczona. Zwłaszcza brak DMA i jakiejkolwiek magistrali do współpracy z zewnętrzną pamięcią są wąskimi gardłami tych prościutkich w gruncie rzeczy układów. Dlatego jeśli mamy mówić o systemie wielozadaniowym/wielowątkowym, to musimy przerzucić się na mocniejsze układy: PIC24, dsPIC i PIC32...

    B Knudsen Data posiada poza dobrymi kompilatorami C system LEANSLICE do tworzenia systemów wielozadaniowych z zastosowaniem algorytmu szeregowania Round robin i maszyny stanów. Jest przeznaczony do współpracy z ichnim kompilatorem CC8E dla mikrokontrolerów PIC18Fxx...

    0
  • #18 28 Wrz 2010 09:58
    marek-c
    Poziom 18  

    Tiaaaa.... do otwierania i zamykania szyb w samochodzie!

    Panowie max 500 bajtów kodu! 6 czujników (2x2 krańcowe 2 przeciążeniowe) 4 przyciski... i jedna pętelka main_loop dobrze przemyślana, tylko nie stosować poolingu a jak już napisano - zdarzenia.


    Urgon napisał:
    AVE...

    8086 jest wydajniejszy, bo ma architekturę CISC i jest procesorem 16-bitowym. A mikrokontrolery w architekturze RISC z zasady nie mają tak przydatnych funkcji, jak DMA i wiele trybów adresowania, zaś bez tego wydajność jest mocno ograniczona. Zwłaszcza brak DMA i jakiejkolwiek magistrali do współpracy z zewnętrzną pamięcią są wąskimi gardłami tych prościutkich w gruncie rzeczy układów. Dlatego jeśli mamy mówić o systemie wielozadaniowym/wielowątkowym, to musimy przerzucić się na mocniejsze układy: PIC24, dsPIC i PIC32...

    B Knudsen Data posiada poza dobrymi kompilatorami C system LEANSLICE do tworzenia systemów wielozadaniowych z zastosowaniem algorytmu szeregowania Round robin i maszyny stanów. Jest przeznaczony do współpracy z ichnim kompilatorem CC8E dla mikrokontrolerów PIC18Fxx...

    0
  • #19 28 Wrz 2010 10:05
    Urgon
    Poziom 36  

    AVE...

    Autor tematu pytał się o wielowątkowość/wielozadaniowość - dostał odpowiedź. Nie ma powodu do czepiania się...

    Nie lepiej mierzyć tylko pobór prądu przez silniki szyb? Gdy silnik elektryczny nie może się obrócić, pobór prądu gwałtownie rośnie. Można tak stwierdzić, czy szyba osiągnęła pozycję krańcową lub nie została zablokowana...

    0
  • #20 28 Wrz 2010 10:21
    marek-c
    Poziom 18  

    Pierwsze pytanie było o szyby! Się nie czepiam - tylko zwracam uwagę że dyskusja idzie w kierunku 'używania armaty do zabicia muchy'.

    A 'oszczędnościowe' rozwiązanie, które kolega sugeruje jest powszechnie stosowane w obecnie produkowanych samochodach (w przeciwieństwie do 'starych konstrukcji - kosztownych') jak wpływa na trwałość - zdaje się nie trzeba pisać.
    Mogę pokazać silniczek z siłownika, który właśnie tak pracuje w Oplu - komutator pięknie stopiony, nic tylko do skupu złomu.
    Oczywiście będzie działać, pod warunkiem że kolocek się nie 'zwiesi' i silniki będą sobie kręcić aż poleci swąd. Tak z doświadczenia: bez problemu zawieszę główną pętlę, a przerwania i np. PWM będą pomykać aż miło!


    Urgon napisał:
    AVE...

    Autor tematu pytał się o wielowątkowość/wielozadaniowość - dostał odpowiedź. Nie ma powodu do czepiania się...

    Nie lepiej mierzyć tylko pobór prądu przez silniki szyb? Gdy silnik elektryczny nie może się obrócić, pobór prądu gwałtownie rośnie. Można tak stwierdzić, czy szyba osiągnęła pozycję krańcową lub nie została zablokowana...

    0
  • #21 28 Wrz 2010 10:33
    Urgon
    Poziom 36  

    AVE...

    PIC16F785 posiada dwa wewnętrzne komparatory(wiele innych PICów ma co najmniej jeden), które generują przerwania - użyć tego w połączeniu z wewnętrznym źródłem napięcia odniesienia. Mierzysz spadek napięcia na rezystorze pomiarowym i porównujesz z napięciem odniesienia ustawionym w mikrokontrolerze. Zmiana, na przykład przekroczenie ustalonej wartości, generuje przerwanie. Póki możesz obsłużyć przerwanie, póty wszystko będzie działać. A co do pętli głównej, to od czego masz watchdog? W przypadku zawieszenia się pętli głównej(czas działania watchdoga się łatwo ustawia) układ jest resetowany łącznie ze wszystkimi rejestrami, co skutecznie wyłączy silniki. Po resecie układ wróci do normalnej pracy...

    0
  • #22 28 Wrz 2010 10:44
    mirekk36
    Poziom 42  

    Panowie, cały temat można załatwić w mega prosty sposób, bez żadnych sztuczek cyrkowych z taką ilością przerwań o jakich piszecie.

    Zdarzenia - to słowo padło już kilka razy choć wiem, że brzmi dla wielu enigmatycznie a można to zrealizować na wiele sposobów.

    Wystarczy JEDEN najprostszy timer sprzętowy tylko po to, żeby albo:

    1. generował tzw: "tyknięcia systemowe" np 100Hz (nie więcej) i informował o tym pętlę główną jakąś flagą

    2. zrbobić na nim ze 2-3 a nawet 4-5 jeśli potrzeba proste "timery programowe"

    Później w pętli głównej albo:

    1. na podstawie licznika "tyknięć systemowych" wykorzystując dzielenie "modulo" precyzyjnie określać najróżniejsze czasy z rozdzielczością do ok 10ms i wykonywać zdarzenia (funkcje) w zależności od tego co dzieje się na jakichś tam wejściach. Można sobie zrobić obsługę typu Debounce bez użycia żadnego "Delay'a" i wykonywać wiele różnych zadań w jednostce czasu jaką będzie np sekunda czy pół sekundy albo i mniej wg potrzeb

    2. W oparciu o ustawienie timera programowego w pętli głównej (a zadawać mu, można odmierzania dowolnych odcinków czasu z rozdzielczością 10ms) - tworzyć obsługę klawiszy z eleiminacją drgań styków i badać stany różnych wejść oraz sterować dowolnymi wyjściami znowu za pomocą funkcji/zdarzeń, które odbywają się w ściśle określonym momencie w zależności od tego co zostanie wykryte na wejściach.

    W oparciu o tak proste jak DRUT mechanizmy zużywam TYLKO JEDNO przerwanie najprostszego TIMERA sprzętowego a mogę je wykorzystać jeszcze do czegoś innego jeśli zajdzie taka konieczność, i robię obsługę np:

    1. Dowolnej ilości klawiszy typu micro-switch na dodatek z funkcją REPEAT gdzie mogę podłączyć wykonanie różnych zdarzeń w zależności od tego czy kliknąłem go raz czy trzymam go przyciśniętego dłużej - np 2s. (ŻADNYCH opóźnień i spowolnień dla pracy pętli głównej!)

    2. obsługę LCD

    3. Obsługę kilku czujników 1wire

    4. Obsługę multipleksowego wyświetlacza LED tyle że tu modyfikuję nieco przerwanie i czasy "sys tick" po to aby przerwanie jako główne zadanie zajmowało się multipleksowaniem a w pętli głównej wyświetlam znowu w dowolnych zdarzeniach to co chcę

    5. Mogę do tego wszystkiego dodać jeszcze obsługę pilota IR jeśli potrzeba - no tyle, że tu zaprzęgnę do pracy jeśli jest to możliwe z uwagi na zasoby sprzętowe procka jeszcze jakieś przerwanie zewn i dodatkowy timer sprzętowy

    6. Pomiary ADC (jeśli jest) z pięknym uśrednianiem

    7. odczyt danych z RTC przez I2C czy SPI (może być softwarowa wersja)

    8. Komunikacja po RS232 (jeśli jest sprzętowe wsparcie to lepiej)

    ..... i co tlko jeszcze dusza zapragnie - a wszystko w jednym czasie i na niewielkim dowolnym małym procku AVR, PIC itp

    (i przyznam tam komuś wyżej rację, że stosowanie przerwań zewnętrznych, których zwykle jest mało do takich celów jak obsługa pojedynczych kilku klawiszy to niestety wg mnie też trochę przerost formy nad treścią bo można to załatwić bez ŻADNEGO zewnętrznego przerwania i to w prostszy sposób niż opisujecie to z użyciem przerwań)





    Wiele osób niestety do takich celów wzięłoby od razu co najmniej jakiegoś ARM'a z możliwością zasadzenia jakiegoś linuxa, który będzie organizował nam zdarzenia systemowe. Często właśnie to, że ktoś nie potrafi sobie poradzić z takim programowaniem opartym o zdarzenia / timery programowe itp - to, to jest motorem do zmiany procesora na większy, ogromny, o dużych możliwościach. Oczywiście nie neguję użycia procków ARM !!! bo zaraz pewne osoby mi to zarzucą ;) .... tylko warto ich użyć wtedy kiedy naprawdę pewnych rzeczy już nie można załatwić zwykłym AVR'kiem czy PIC'em. Chociaż zdaję sobie sprawę , że dla każdego ta granica możliwości to właśnie pojęcie względne. Dla mnie zaczyna się ona wtedy gdy np rzeczywiście nie wyrabiam się z transferem dużej (naprawdę dużej ilości danych i przydałoby się sprzętowe DMA), gdy np miałbym robić obsługę plików graficznych jpeg czy analizy obrazu z kamerki, albo robić nieco bardziej zaawansowany pracujący w lokalnej sieci serwerek HTTP itd itd itd

    Reasumując panie autor ;) ... to rozpisałem się tu co niemiara a kodu programu do twojego zadania wyszłoby tyle co kot napłakał żeby to zrealizować w oparciu o to co opisałem na jednym małym procku - zatem do dzieła ;) .... wystarczy poprzeglądać sobie kody porządnych programów, bibliotek - żeby podejrzeć właściwe podejście a potem wdrażać te pomysły u siebie.

    Dodano po 1 [minuty]:

    marek-c napisał:
    Się nie czepiam - tylko zwracam uwagę że dyskusja idzie w kierunku 'używania armaty do zabicia muchy'.
    ... oo to chodzi ;) ( a nawet już za chwilę bomby atomowej )

    0
  • #24 28 Wrz 2010 12:38
    janbernat
    Poziom 38  

    mirekk- bardzo ładnie wytłumaczyłeś to co napisałem wcześniej. :D
    Nawet w Bascomie tak robiłem.

    0
  • #25 28 Wrz 2010 12:49
    mirekk36
    Poziom 42  

    janbernat --> no widzisz - tak to już jest. Z jednej strony łatwo mówić tym, którzy już sobie dobrze radzą z programowaniem, do początkującego, że nP:

    - zastosuj sobie zdarzenia
    - zastosuj sobie wątki
    - zastosuj sobie timery programowe

    tymczasem osoba, która nie ma jeszcze o tym zielonego pojęcia - przedzie nad taką podpowiedzią bez echa i się nie dziwię z jednej strony.

    Z drugiej zaś strony, sam wiem , że nie sposób takich zagadnień opisać w kilku zdaniach np na forum, można tylko próbować podawać jakieś wskazówki a i tak co implementacja i co programista to będzie z tym inaczej i to jest normalne. Tyle, że wskazówki jednego dotrą do pewnej części osób a wskazówki drugiego do jeszcze innych - tu nie ma jakiejś uniwersalnej zasady na wytłumaczenie tego w 2 zdaniach. Zatem i twój opis jest dobry i być może mój - chociaż w szczegółach na pewno robimy to całkowicie inaczej i nie mówię tu o tym, że ja teraz w C a ty w Bascomie - bo to nie ma znaczenia. Ja wcześniej też pisałem kiedyś w Bascomie. Chociaż znaczenie ma to ogromne w jakim języku robi się taką implementację - bo "zważ" sobie chociażby swoje przerwanie "sys tick" napisane w Bascomie a np w asemblerze czy C. A to potrafi ograniczyć możliwości gdy potrzebujemy lepszej/szybszej podstawy czasu.

    0
  • #26 28 Wrz 2010 13:10
    nsvinc
    Poziom 35  

    Wielowątkowość "zasymulowana" może opierać się na funkcjach (udających procesy) w ktorych uzyte zostaly zmienne lokalne typu static. Taka funkcja co kilka-kilkanascie linijek kodu robi return do pętli głównej....

    Code:

    void wontek1(void *arg) //niech sobie pracuje na jakims przekazanym wsk. na void
    {
    static unsigned int a=0,b=0,c=0; //jakies zmienne
    static unsigned int przelacznik=0;
    przelacznik++;
    if (przelacznik>4) przelacznik=1;
    switch(przelacznik)
    {

    case 1: { [tu jakis kod]  }; return;
    case 2: { [tu tez jakis kod] }; return;
    case 3: { [tu jakis inny kod] }; return;
    case 4: { [tu jakis kod] }; return;

    }

    }

    Wywolujac takie funkcje cyklicznie w petli glownej uzyskujemy dobrą ściemę wielozadaniowości, bo funkcje wykonuja jakis fragment kodu po czym robia return i przekazuja kontrole jakiejs innej funkcji....

    0
  • #27 28 Wrz 2010 13:51
    Urgon
    Poziom 36  

    AVE...

    Wszystko świetnie, ale co będzie, jak jakaś funkcja będzie musiała czekać na określone zdarzenie? Trza pisać program tak, by nie czekała, a jedynie sprawdzała, czy zdarzenie miało miejsce...
    Można to uprościć eliminując skoki warunkowe IF i SWITCH, i pisząc po prostu klasyczny program sekwencyjny. Te skoki mogą się przydać tylko wtedy, gdy podprogramy w celu wykonania zadań będą zmieniały wartość zmiennej przelacznik w miarę potrzeby. A wtedy można zrobić coś takiego:

    Code:
    void wontek1(void *arg) //niech sobie pracuje na jakims przekazanym wsk. na void
    
    {
    static unsigned int a=0,b=0,c=0; //jakies zmienne
    static unsigned int przelacznik=0;
    static unsigned int blokada=0; //blokada zmiany wartosci, coby nic sie nie posypalo
    if (blokada=1) blokada=0; else przelacznik++;
    if (przelacznik>4) przelacznik=1;
    switch(przelacznik)
    {

    case 1: { [tu jakis kod]  }; return;
    case 2: { [jakis kod zmieniajacy sekwencje w razie stanu]
    if (a=1)
    {
    blokada=1;
    przelacznik=1;
    }
    }; return;
    case 3: { [tu jakis inny kod] }; return;
    case 4: { [tu jakis kod] }; return;

    }

    }

    Po spacerze z psem oświeciło mnie: dodatkowy warunek nie będzie potrzebny tak długo, jak długo programista będzie pamiętał, by nadać zmiennej przelacznik wartość o 1 mniejszą od tego, do którego przypadku CASE chce skoczyć. Ale jeśli takich rzeczy nie ma zamiaru robić, to całość może wyglądać tak:
    Code:
    void wontek1(void *arg) //niech sobie pracuje na jakims przekazanym wsk. na void
    
    {
    static unsigned int a=0,b=0,c=0; //jakies zmienne
    [tu jakis kod]
    [tu takze jakis kod]
    [tu jakis inny kod]
    [tu jakis kod]
    }

    Swoją drogą na elektrodzie powinien być wydzielony temat poświęcony tylko i wyłącznie takim zagadnieniom dla początkujących...

    0