pisze sobie RTOSa na 8bitowe procesorki Atmela. oczywiscie podstawa kazdego systemu operacyjnego jest multitasking i tu moje pytanie: jak sensownie zaimplementowac context switching? lookalem do wielu kodow zrodlowych ale kazdy bazuje na kodzie z FreeRTOS (ktory jest do bani, nie mowiac o tym, ze go nie rozumiem ;( ). moze istnieje jakies roziwazanie na x86, ktore mozna przeniesc?
Podmiana stosow, pushujesz wszystkie rejestry, zamieniasz stos na stos inneego procesu, popujesz wszystko i juz :)
geez :/ no wlasnie tak robi FreeRTOS. cholera no nie kumam tego za chiny [sciana]. mozna krok po kroku? kiedy mam zapisac stack pointer? kiedy wczytac stos innego procesu itd? wystarczy tak mini lista reszte pokumam.
Nie znam sie na prockach pod ktore piszesz ale w x86 wyglada to tak:
- wywoluje sie irq zegara
- w funkcji oblugujacej przerwanie pushujesz wszystkie rejestry
- podmieniasz stos
- popujesz wszystko
- iret
Kazdy proces ma swoj stos oczywiscie i przy dodawaniu jakiejs aplikacji jak zaalokujesz jej srodowisko (miejsce na kod, dane, stos, sterte itp) to musisz jeszcze zapisac odpowiednie wartosci na tym stosie.
Mowa tutaj o procesach pracujacych na ring0, z zamiana ringow to troszke inaczej wyglada.
Mogę spytać na jaki konkretnie procek piszesz?
no nie pisze na konkretny model, chcialbym zeby byla mozliwosc uzywania tego OSa na wszystkich (a chociaz wiekszosci) modelach. jakkolwiek do testow uzywam 90s2313 i pozniej moze atmega16.
ale z ludzi trzeba wszystko wyciagac na sile :d
-
wywoluje sie irq zegara
-> proste, to akurat wiem, a najlepiej jeszcze wtedy wylaczyc przerwania wszystkie -
w funkcji oblugujacej przerwanie pushujesz wszystkie rejestry
-> znaczy wszystkie rejestry zastane w momencie wejscia do dispatch() po prostu klade na sto? -
podmieniasz stos
-> skad mam ten stos wziac, moglbys troche rozwinac? -
popujesz wszystko
-> popuje te rejestry, ktore pushowalem na poczatku funkcji?
a gdzie w tym wszystkim mam robic zapisywanie stack pointera?
vixen03 napisał(a)
- podmieniasz stos
-> skad mam ten stos wziac, moglbys troche rozwinac?
Dla kazdego nowo stworzonego procesu alokujesz stos, zapisujesz jego sp np w jakiejs tablicy, potem ustawiasz pokolei w tym momencie.
vixen03 napisał(a)
a gdzie w tym wszystkim mam robic zapisywanie stack pointera?
No wlasnie tu, zapomnialem wspomniec, ze stary sp zapisujesz w tej tablicy (w ring0-3 tego nie trzeba bylo robic) :)
vixen03 napisał(a)
-> znaczy wszystkie rejestry zastane w momencie wejscia do dispatch() po prostu klade na sto?
Nie bardzo kapuje co tu jest napisane.
Mały problem z 90s2313: on ma 32 rejestry (8bit) ogólne i tylko 128 bajtów ramu...
sic! chyba zle zadalem pytanie :-/ poprawiam je wiec: jak krok po kroku zrobic context switching? nie chce kodu, wystarczy slownie.
z tego co ja rozumiem do tej pory to jest tak:
-
tworze nowe zadanie: przydzielam mu strukture na rejestry, stack pointer itd. jednym slowem TCB_A
-
tworze drugie zadanie TCB_B
-
w irq zegara co pewien czas odpala sie dispatch(), wylaczam przerwania, rejestry sa juz czyms zawalone, na stosie tez sa jakies dane. cos z nimi trzeba zrobic. no wlasnie. zapisuje tylko stack pointer w TCB_A czy caly stos ktory w tej chwili mam?
-
z TCB_B zczytuje rejestry, stack pointer (czy caly stos?) itd i pakuje je na swoje miejsca.
-
Task_B cos tam mieli, miesza na stosie w rejestrach
-
no i znow rejestry do pamieci i znow task pointera (albo caly stos trzeba zapakowac) do TCB_B
-
zgrywam dane z TCB_A i tak w kolko.......
dobrze to jest czy ja cos piernicze? cholernie ciezko sobie wyobrazic stos i 32 rejestry an raz ;)
128 bajtow ramu pozwoli chyba na odpalenie 3 taskow? licze ze kazdy task dostanie te 32-35 bajtow na TCB a reszta na biezace uzytkowanie i na NULLtaska. a moze i tu cos mi sie chrzani i zle licze?
SP tylko zapisujesz, stosy dla tych dwoch procesow sa w innym miejscu.
Qyon napisał(a)
Mały problem z 90s2313: on ma 32 rejestry (8bit) ogólne i tylko 128 bajtów ramu...
Do takich rzeczy sie nie robi osa z wielozadaniowoscia :P