eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › printf i wielozadaniowosc (MicroC/OS-II)
Ilość wypowiedzi w tym wątku: 21

  • 1. Data: 2009-09-29 15:42:52
    Temat: printf i wielozadaniowosc (MicroC/OS-II)
    Od: "Pszemol" <P...@P...com>

    W systemie MicroC/OS-II wszystkie wątki uszeregowane są według swoich
    priorytetów i wątek o niższym priorytecie dostaje procesor TYLKO WTEDY
    gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na zdarzenie.

    W swoim programie wielowątkowym dorobiłem na szybkiego logowanie
    zdarzeń w celach debugging i używam "zakazanej" funkcji printf, jako że jest
    ona bardzo wygodna zwłaszcza z parsingiem argumentów typu %d lub %x
    w tekście... :-)

    Spodziewałem się jakichś efektów związanych z niereentrantnością tej
    funkcji, ale to co dostałem trochę mnie zaskoczyło...

    Otóż co widzę, to że na wyjściu generowanym przez tą funkcję fprintf
    (strumień znaków RS232, "plikiem" dla fprintf jest port szeregowy)
    widzę że wątek o niższym priorytecie wchodzi z butami w linię tekstu
    wątka o wyższym priorytecie i wcięcie jest tam, gdzie fprintf robi ten
    parsing argumentów %d.

    Podam przykłady.
    Oto niezaburzona linia z tasku o najwyższym priorytecie (Barrier 0):

    "Barrier 0: s:14 M: a8c09, M: b98f, M: 6e71b, M: d14a5, M: 3422e, M: 96ff6,
    M: f9d77"

    A oto podobna linia z wcięciami się od tasków o niższych priorytetach
    (Barrier 4):

    "Barrier 0: s:14 M: c5aa5Barrier 4: handling legacy sensor readings
    (time:1607)
    Barr 4: Decrement counter (26) for legacy sensor (time:1607)
    Barrier task 4, 'unknown' - wait one dev delay increment... (time:1608)
    , M: 28521, M: 8b227, M: eddfc, M: 50b03, M: b365c, M: 223b1, M: 66cf0"

    Task o priorytecie 3 schodki niżej, wciął się w środek fprintf'a od tasku
    o prawie najwyższym priorytecie i to w miejscu, gdzie skończyło się
    parsowanie argumentu %x i zaczął text printf'a.

    Tu inny przykład, ta sama sytuacja (barrier 7 to task o priorytecie 8):
    "Barrier 0: s:09 R: 152ba, R: 78080Barrier 7: handling legacy sensor
    readings (time:1613)
    Barr 7: Decrement counter (42) for legacy sensor (time:1613)
    Barrier task 7, 'unknown' - wait one dev delay increment... (time:1613)
    , R: dae06, R: 3db91, R: a091a, R: 36a4, R: 66445, R: c91aa"

    Jak wytłumaczyć takie efekty?

    Rozumiem, że skoro wywołania fprintf'a z tasków dotyczą tego samego
    portu szeregowego, przekazanego fprintf'owi jako argument nazwy pliku
    (globalna zmienna) to może się coś kiepścić, i linie się będa przeplatać,
    ale nie rozumiem jak taski o niższym priorytecie mogły się wstrzelić
    z TRZEMA OSOBNYMI WYWOŁANIAMI fprintf'a w jedną linię tasku
    o wyższym priorytecie? Przecież według filozofii MicroC/OS-II task
    bariery 0, w czasie chodzenia sobie po kodzie fprintfa nie powinien być
    przerwany i taski o priorytetach 4 czy tym bardziej 8 powinny grzecznie
    czekać aż fprintf wywołany przez task o priorytecie 1 ukończy zadanie
    i odda sterowanie systemowi operacyjnemu (nie ma tu wywłaszczania).

    Czy ktoś mógłby mi to wytłumaczyć?


  • 2. Data: 2009-09-29 16:18:21
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: Zbych <z...@o...pl>

    Pszemol pisze:

    > gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na zdarzenie.
    [...]
    > Otóż co widzę, to że na wyjściu generowanym przez tą funkcję fprintf
    > (strumień znaków RS232, "plikiem" dla fprintf jest port szeregowy)
    > widzę że wątek o niższym priorytecie wchodzi z butami w linię tekstu
    > wątka o wyższym priorytecie
    [...]
    > Czy ktoś mógłby mi to wytłumaczyć?

    Żeby to dobrze wytłumaczyć to trzeba zobaczyć jak to jest
    zaimplementowane. Szklana kula mówi tylko, że wątek o wyższym
    priorytecie oddaje czas innym wątkom, bo czeka na zwolnienie miejsca w
    buforze nadawczym RSa. Przy czym nie masz żadnej gwarancji, że po
    zwolnieniu miejsca pierwszy do RSa dobierze się wątek o najwyższym
    priorytecie. Żeby wiedzieć co się dzieje to trzeba by na osobnym kanale
    wyrzucać kiedy i jakie wątki są uruchamiane.


  • 3. Data: 2009-09-29 16:47:34
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: "Pszemol" <P...@P...com>

    "Zbych" <z...@o...pl> wrote in message news:h9tc37$135h$1@news.mm.pl...
    > Pszemol pisze:
    >
    >> gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na
    >> zdarzenie.
    > [...]
    >> Otóż co widzę, to że na wyjściu generowanym przez tą funkcję fprintf
    >> (strumień znaków RS232, "plikiem" dla fprintf jest port szeregowy)
    >> widzę że wątek o niższym priorytecie wchodzi z butami w linię tekstu
    >> wątka o wyższym priorytecie
    > [...]
    >> Czy ktoś mógłby mi to wytłumaczyć?
    >
    > Żeby to dobrze wytłumaczyć to trzeba zobaczyć jak to jest
    > zaimplementowane. Szklana kula mówi tylko, że wątek o wyższym priorytecie
    > oddaje czas innym wątkom, bo czeka na zwolnienie miejsca w buforze
    > nadawczym RSa. Przy czym nie masz żadnej gwarancji, że po zwolnieniu
    > miejsca pierwszy do RSa dobierze się wątek o najwyższym priorytecie. Żeby
    > wiedzieć co się dzieje to trzeba by na osobnym kanale wyrzucać kiedy i
    > jakie wątki są uruchamiane.

    To jest oczywista oczywistość, że wątek o priorytecie 1 czeka na port
    RS i oddaje sterowanie :-) Mnie interesuje jak to się dzieje, że w czasie
    gdy task 1 oddał sterowanie task 4 lub 7 był wstanie trzy razy wysłać
    linię znaków do RS'a trzema osobnymi wywołaniami fprintfa...

    Tu masz przykład:

    "Barrier 0: s:14 M: c5aa5Barrier 4: handling legacy sensor readings
    (time:1607)
    Barr 4: Decrement counter (26) for legacy sensor (time:1607)
    Barrier task 4, 'unknown' - wait one dev delay increment... (time:1608)
    , M: 28521, M: 8b227, M: eddfc, M: 50b03, M: b365c, M: 223b1, M: 66cf0"

    To wyżej to był efekt 4 osobnych wywołan funkcji fprintf:

    task1 (barrier 0) zrobił najpierw to:

    fprn(probe_out, "Barrier %d: s:%02ld M:%6lx, M:%6lx, M:%6lx, M:%6lx,
    M:%6lx, M:%6lx, M:%6lx\r\n",

    i w trakcie gdy utknął w tej linii czekając na RSa task 5 (barrier 4) zrobił
    to:

    fprn(barr_out, "Barrier %d: handling legacy sensor readings
    (time:%ld)\r\n",

    potem to w zupełnie innym miejscu kodu:

    fprn(barr_out, "Barr %d: Decrement counter (%ld) for probe #%d
    (time:%ld)\r\n",

    i za moment to:

    fprn(barr_out, "Barrier task %d, '%s' - wait one dev delay
    increment... (time:%ld)\r\n",

    w czasie gdy task 1 wisiał sobie i czekał na zwolnienie RSa...


    Tak czy inaczej muszę przerobić to aby zostało to w kodzie na dłużej.
    Chyba zrobię nowy task o najniższym priorytecie który zajmie się
    odbiorem tekstów od tasków roboczych o wyższych priorytetach
    i wstawianiem tych tekstów do portu szeregowego...


  • 4. Data: 2009-09-29 16:59:54
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: A.L. <a...@a...com>

    On Tue, 29 Sep 2009 10:42:52 -0500, "Pszemol" <P...@P...com>
    wrote:

    >
    >Jak wytłumaczyć takie efekty?
    >
    [...]
    >
    >Czy ktoś mógłby mi to wytłumaczyć?

    JA sie bardzd dawno tym zajmowlem i pod zupelnie inym systeme, a
    bardzo dzawno znaczy BARDZO dawno. Ale mialem podobny problem

    1. Task o wysokim priorytecie pisze do UART. UART ma wlasny bufor.
    Bufor sie przepelnil i taksk dostal notyfikacje. System zawiesil task.

    2. Wiec task o niskim priorytecie dostal CPU; w miedzyczasie UART
    zaczal oproznaic budor, wiec taks o niskim priorytecie mogl pisac. Po
    niedlugim czasie system zauwazyl ze task o wysokim priorytecie czeka
    na UART, wiec zasiesil task o niskim priorytecie i ten zaczal pisac do
    UART

    W efekcie wyszla "sieczka" zlozona z fragmentow informacji z roznych
    taskow.

    Kluczowe pytanie jes co to znaczy ze printf "zakonczyl" dzialanie.
    Powinien raportowac "zakonczenie" dzialania tylko wdedy gdy informacja
    zostala rzeczywiscie fizycznie wyslana do klienta.

    Nie wiem jak to jest w twoim systemie, ale podejrzewam ze cos takiego
    lub podobnego.

    Remedium byloby zamkniecie printf w osobnym tasku z wlasnum,
    nieograniczonym buforem i potraktowanei calosci jako sekcji krytycznej

    A.L.


  • 5. Data: 2009-09-29 18:08:08
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: grg12 <g...@c...at>

    Pszemol pisze:
    > W systemie MicroC/OS-II wszystkie wątki uszeregowane są według swoich
    > priorytetów i wątek o niższym priorytecie dostaje procesor TYLKO WTEDY
    > gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na zdarzenie.
    >

    A aktywny wątek o niskim priorytecie może zostać przymusowo "uśpiony" na
    rzecz wątku wysokopriorytetowego czy przełączenie następuje tylko jeśli
    aktywny watek dobrowolnie odda sterowanie (tak było w np. win3.1)?
    Przypuśćmy że wątek HiPrio pisze sobie coś do bufora łącza szeregowego,
    bufor zostaje zapełniony więc wątek zostaje uśpiony do czasu opróżnienia
    bufora, wątek LowPrio przejmuje pałeczkę, po pewnym czasie próbuje
    zapisać do bufora łącza, który został już opróżniony przez obsługę portu
    szeregowego (jakieś przerywanie zapewne) - wypisuje swoje i grzecznie
    idzie spać. W tym momencie obudzony zostaje wątek HiPrio...
    Pozdrawiam
    GRG


  • 6. Data: 2009-09-29 18:35:49
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: "Pszemol" <P...@P...com>

    "grg12" <g...@c...at> wrote in message
    news:25a0$4ac24d00$506cdd75$32156@news.chello.at...
    > Pszemol pisze:
    >> W systemie MicroC/OS-II wszystkie wątki uszeregowane są według swoich
    >> priorytetów i wątek o niższym priorytecie dostaje procesor TYLKO WTEDY
    >> gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na
    >> zdarzenie.
    >
    > A aktywny wątek o niskim priorytecie może zostać przymusowo "uśpiony"
    > na rzecz wątku wysokopriorytetowego czy przełączenie następuje tylko jeśli
    > aktywny watek dobrowolnie odda sterowanie (tak było w np. win3.1)?

    Wysoki priorytet zwykle śpi bo czeka np. na przerwanie od zegara
    lub od urządzenia zewnętrznego, np. RS232. Czyli masz przerwanie
    które przychodzi od RS232 a jesteś w tasku o priorytecie 3 to system
    obsługuje przerwanie i po obsłudze znowu sprawdza gdzie wrócić.
    Ponieważ mam dwa taski gotowe, task o priorytecie 1 czekał na RS232
    a już nie czeka, to task 1 powinien dostać sterowanie...

    Podsumowując, nie dziwiłbym się że w linii loga od tasku 3 mam
    przerwy i z buciorami wchodzi task 0 czy 1 ze swoim tekstem...
    Ja się dziwię że linia od tasku 0 została przerwana w połowie
    i wszedł w jej środek task 3 Z TRZEMA WYWOŁANIAMI fprintf'a.

    > Przypuśćmy że wątek HiPrio pisze sobie coś do bufora łącza szeregowego,
    > bufor zostaje zapełniony więc wątek zostaje uśpiony do czasu opróżnienia
    > bufora, wątek LowPrio przejmuje pałeczkę, po pewnym czasie próbuje zapisać
    > do bufora łącza, który został już opróżniony przez obsługę portu
    > szeregowego (jakieś przerywanie zapewne) - wypisuje swoje i grzecznie
    > idzie spać. W tym momencie obudzony zostaje wątek HiPrio...

    Ja nie widzę tutaj możliwości aby z dwu tasków czekających na
    przerwanie od portu szeregowego dorwał się do RS232 ten
    o niższym priorytecie i to w połowie parsingu od fprintfa HiPrio.


  • 7. Data: 2009-09-29 20:46:22
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: Adam Dybkowski <a...@4...pl>

    Pszemol pisze:

    > Rozumiem, że skoro wywołania fprintf'a z tasków dotyczą tego samego
    > portu szeregowego, przekazanego fprintf'owi jako argument nazwy pliku
    > (globalna zmienna) to może się coś kiepścić, i linie się będa przeplatać,
    > ale nie rozumiem jak taski o niższym priorytecie mogły się wstrzelić
    > z TRZEMA OSOBNYMI WYWOŁANIAMI fprintf'a w jedną linię tasku
    > o wyższym priorytecie?

    Może chodzi o to, że [f]printf wywołany z zadania o wysokim priorytecie
    jest dzielony na wiele odrębnych zapisów do portu szeregowego (w
    najprostszej implementacji będą to zapisy po jednym znaku) a system
    operacyjny w oczekiwaniu na gotowość portu do przyjmowania kolejnych
    znaków (zgłaszaną zapewne w przerwaniu portu szeregowego) oddaje po
    prostu sterowanie zadaniom o niższym priorytecie gotowym do wykonania. W
    gruncie rzeczy to chyba lepsze podejście (a nuż zadanie o niskim
    priorytecie cośtam sobie liczy powoli w tle) niż aktywne oczekiwanie na
    zwolnienie się miejsca w buforze nadajnika portu szeregowego. Czasem
    przy wolnej transmisji i długim buforze sprzętowym (zależy od procesora
    lub zewnętrznego układu UART) takie oczekiwanie byłoby długie - a tak w
    tym czasie procesor może się zająć obsługą zadań o niższym priorytecie.

    Aby uniknąć takiego mieszania się printf'ów, wystarczy objąć je
    semaforem / mutexem czy co tam masz podobnego w tym systemie.

    --
    Adam Dybkowski
    http://dybkowski.net/

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


  • 8. Data: 2009-09-29 21:04:24
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: Jerry1111 <j...@w...pl.pl.wp>

    Pszemol wrote:
    > W systemie MicroC/OS-II wszystkie wątki uszeregowane są według swoich
    > priorytetów i wątek o niższym priorytecie dostaje procesor TYLKO WTEDY
    > gdy wątek o wyższym priorytecie nie ma nic do roboty i czeka na zdarzenie.
    >
    > W swoim programie wielowątkowym dorobiłem na szybkiego logowanie
    > zdarzeń w celach debugging i używam "zakazanej" funkcji printf, jako że
    > jest
    > ona bardzo wygodna zwłaszcza z parsingiem argumentów typu %d lub %x
    > w tekście... :-)

    Wcale nie jest zakazana.

    > Spodziewałem się jakichś efektów związanych z niereentrantnością tej
    > funkcji, ale to co dostałem trochę mnie zaskoczyło...

    Bo tu nie chodzi o printf, tylko o reentrancje calej biblioteki newlib.
    Z drugiej strony Altera ma to zalatwione, wiec nie rozumiem czemu problem?

    > Otóż co widzę, to że na wyjściu generowanym przez tą funkcję fprintf
    > (strumień znaków RS232, "plikiem" dla fprintf jest port szeregowy)
    > widzę że wątek o niższym priorytecie wchodzi z butami w linię tekstu
    > wątka o wyższym priorytecie i wcięcie jest tam, gdzie fprintf robi ten
    > parsing argumentów %d.

    Bo nie masz tego jako atomic operation. Jestem na 99% pewny ze jako
    atomic jest tylko zrobione wysylanie pojedynczych znakow.

    Ma to sens, bo inaczej blokowalbys system na dosc dlugi czas (chyba ze
    masz duze fifo - wtedy mozna sie o to pokusic).


    > Task o priorytecie 3 schodki niżej, wciął się w środek fprintf'a od tasku
    > o prawie najwyższym priorytecie i to w miejscu, gdzie skończyło się
    > parsowanie argumentu %x i zaczął text printf'a.

    Bo w miedzyczasie byla zmiana kontekstu. Czemu? Bo wyzszy watek czekal
    na wyslanie znaku...

    > Rozumiem, że skoro wywołania fprintf'a z tasków dotyczą tego samego
    > portu szeregowego, przekazanego fprintf'owi jako argument nazwy pliku
    > (globalna zmienna) to może się coś kiepścić, i linie się będa przeplatać,
    > ale nie rozumiem jak taski o niższym priorytecie mogły się wstrzelić
    > z TRZEMA OSOBNYMI WYWOŁANIAMI fprintf'a w jedną linię tasku
    > o wyższym priorytecie? Przecież według filozofii MicroC/OS-II task
    > bariery 0, w czasie chodzenia sobie po kodzie fprintfa nie powinien być
    > przerwany i taski o priorytetach 4 czy tym bardziej 8 powinny grzecznie
    > czekać aż fprintf wywołany przez task o priorytecie 1 ukończy zadanie
    > i odda sterowanie systemowi operacyjnemu (nie ma tu wywłaszczania).
    >
    > Czy ktoś mógłby mi to wytłumaczyć?

    A jak w priority 0 wstawic OSTimeDly(10), to tez nic innego sie nie
    uruchomi? AFAIR driver usart Altery czeka na signal jak ma pelny bufor,
    wiec w miedzyczasie inny watek idzie.


    --
    Jerry1111


  • 9. Data: 2009-09-29 22:06:11
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: "Pszemol" <P...@P...com>

    "Jerry1111" <j...@w...pl.pl.wp> wrote in message
    news:h9tsp1$pfi$1@news.onet.pl...
    > Wcale nie jest zakazana.

    Dlatego ująłem to w cudzysłów :-)

    > Bo tu nie chodzi o printf, tylko o reentrancje calej biblioteki newlib. Z
    > drugiej strony Altera ma to zalatwione, wiec nie rozumiem czemu problem?

    No tak to ma załatwione że wcina się task 4 lub 7 w środek linii tasku 1.

    > Bo nie masz tego jako atomic operation. Jestem na 99% pewny ze jako atomic
    > jest tylko zrobione wysylanie pojedynczych znakow.
    >
    > Ma to sens, bo inaczej blokowalbys system na dosc dlugi czas (chyba ze
    > masz duze fifo - wtedy mozna sie o to pokusic).

    Dla dodania tła do zagadnienia:
    Fifo softwareowe jest 64 znaki. Uart pracuje z baud 115200
    bez handshake i procesor NiosII-e biega z zegarem 80MHz...

    Przerwy w linii od tasku 1 są ZAWSZE przy granicy argumentu do
    printfa (albo przed %d albo po). Nigdy nie przerywa w trakcie tak
    aby urwało w środku wyrazu czy też w środku zmiennej integer :-)
    Dlatego nie bardzo mi się chce wierzyć, że kwestia jest w wysyłaniu
    znak po znaku - raczej chodzi o parser printfa.

    >> Task o priorytecie 3 schodki niżej, wciął się w środek fprintf'a od tasku
    >> o prawie najwyższym priorytecie i to w miejscu, gdzie skończyło się
    >> parsowanie argumentu %x i zaczął text printf'a.
    >
    > Bo w miedzyczasie byla zmiana kontekstu. Czemu?
    > Bo wyzszy watek czekal na wyslanie znaku...
    [...]
    > A jak w priority 0 wstawic OSTimeDly(10), to tez nic innego sie nie
    > uruchomi? AFAIR driver usart Altery czeka na signal jak ma pelny bufor,
    > wiec w miedzyczasie inny watek idzie.

    Oczywiście niższe taski mogą działać tylko wtedy gdy wyższy czeka.
    To wiem. Natomiast interesujące jest że przerwa i wcięcie się niskiego
    tasku w linię wysokiego jest nie w przypadkowym miejjscu tylko
    na granicy argumentu do printfa.


  • 10. Data: 2009-09-30 13:25:22
    Temat: Re: printf i wielozadaniowosc (MicroC/OS-II)
    Od: Zbych <a...@o...pl>

    Pszemol pisze:

    > To jest oczywista oczywistość, że wątek o priorytecie 1 czeka na port
    > RS i oddaje sterowanie :-) Mnie interesuje jak to się dzieje, że w czasie
    > gdy task 1 oddał sterowanie task 4 lub 7 był wstanie trzy razy wysłać
    > linię znaków do RS'a trzema osobnymi wywołaniami fprintfa...

    Ktoś na pme podpowiedział ci, żebyś sprawdził, czy prawidłowo ustawiłeś
    priorytety wątków. Od siebie dorzucę tylko pytanie: czy ten system
    gwarantuje ci, że jak bufor RSa będzie wolny to w pierwszej kolejności
    dobierze się do niego wątek o najwyższym priorytecie? A może kto
    pierwszy ten lepszy?

strony : [ 1 ] . 2 . 3


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: