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.

[Cortex-M3 STM32L152][arm-gcc] - Aplikacja wielowątkowa, przełączanie kontekstu

cabadath 28 Sty 2014 20:30 1779 12
  • #1 28 Sty 2014 20:30
    cabadath
    Poziom 6  

    Witam!

    Od jakiegoś czasu usiłuję napisać aplikację obsługującą kilka wątków (taki wstęp do RTOS) i przełączającą kontekst między nimi. Problem tkwi w tym, że podczas wczytywania kontekstu (LoadContext()) wywala FaultHandler. Zdebugowałem ustrojstwo i wynikiem są dwa bity CFSR: IMPRECISERR oraz STKERR. Nie wiem co może być przyczyną, być może czegoś nie inicjalizuje, może podaję zły typ. W każdym razie z dokumentacji wynika, że albo na stosie jest jakaś zła wartość, albo został źle zainicjalizowany. Jeśli chodzi o skrypt linkera i startup, to nie ruszałem ich, są domyślne. Używam STM32L152 Discovery, choć nie ma to większego znaczenia.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 12
  • #2 28 Sty 2014 21:16
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Tak sobie na to patrzę i wydaje mi się, że to nie ma prawa działać. Przełączanie kontekstu moim zdaniem musi się odbywać _W_ przerwaniu, Ty natomiast w przerwaniu jedynie sygnalizujesz że główny kod ma przełączyć wątek, no ale niby jak? Więc wywala Ci się, gdyż nagle podmieniasz AKTUALNIE używany wskaźnik stosu.

    4\/3!!

    0
  • #3 28 Sty 2014 21:40
    cabadath
    Poziom 6  

    Zmieniłem przerwanie na:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    oraz inicjalizację na:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Ciągle się wykrzacza, tym razem jest SHCSR na SYSTICKACT. Tak się zastanawiam czy samo ustawienie stosu przez __set_PSP wystarcza w inicjalizacji? Bo jeśli nie, to mi się już wyczerpują pomysły jak można zainicjalizować stos. A może w ogóle nie trzeba?

    0
  • #4 28 Sty 2014 21:50
    Freddie Chopin
    Specjalista - Mikrokontrolery

    cabadath napisał:
    Tak się zastanawiam czy samo ustawienie stosu przez __set_PSP wystarcza w inicjalizacji?

    Tego nie można tak zrobić, bo po takiej podmianie powrót z tej funkcji spowoduje "pad". Pierwsze przełączenie (a w zasadzie "włączenie") powinno być tak samo wykonane przez przerwanie i tak musisz to zmienić. Używając PendSV naprawdę jest prościej <:

    4\/3!!

    0
  • #5 28 Sty 2014 23:42
    cabadath
    Poziom 6  

    No więc przepraszam, że jestem głąbem i się zamotałem, ale bardzo bym chciał to zrozumieć. Ustawiłem PendSV chyba tak jak trzeba. Ustawiłem jego priorytet na 0xff i nie wiem czemu ustawiony jest na 0xf0. W każdym razie "wymuszam" wywołanie PendSV w funkcji asm, którą napisałem w startupie.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Teraz tak: nadal nie wiem gdzie zainicjalizować PSP po raz pierwszy. Ustawienie rejestru CONTROL w przerwaniu nie ma chyba sensu, bo przerwania są obsługiwane przez MSP, więc i tak po uruchomieniu ma wartość 0. Tym razem wysypuje się na LoadContext(). W teorii rozumiem, że trzeba ustawić CONTROL na PSP, potem załadować na PSP pierwsze zadanie.

    Tutaj pendsv_call:
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    0
  • #6 29 Sty 2014 08:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Skoro masz debugger to przecież możesz prześledzić krok po kroku co się dzieje, patrząc szczególnie na to, czy nie masz gdzieś odczytów/zapisów z/do nieistniejącej pamięci.

    cabadath napisał:
    Ustawienie rejestru CONTROL w przerwaniu nie ma chyba sensu, bo przerwania są obsługiwane przez MSP, więc i tak po uruchomieniu ma wartość 0

    No i co z tego, przecież CONTROL jest tylko jedno, więc co za różnica gdzie go ustawisz?

    Zaczęło mnie też ciekawić to:
    cabadath napisał:
    Jeśli chodzi o skrypt linkera i startup, to nie ruszałem ich, są domyślne

    Co to są "domyślne" skrypty linkera i startup?

    4\/3!!

    0
  • #7 29 Sty 2014 09:28
    cabadath
    Poziom 6  

    Domyślne, nie zmieniałem niczego.

    Skrypt linkera:

    Kod: asm
    Zaloguj się, aby zobaczyć kod



    startup:

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    Zastanawiam się czy przypadkiem nie powinienem ustawić osobno MSP i PSP w skrypcie linkera... Nigdy nie zmieniałem skryptu linkera, nie było mi to potrzebne, więc nie bardzo się orientuję.

    0
  • #9 30 Sty 2014 12:23
    cabadath
    Poziom 6  

    Ok, więc uprościłem trochę program, znalazłem przykład z cytuję "prymitywnym" przełączaniem kontekstu, ale do debugowania jest świetny, bo ilość operacji jaka się w nim dzieje jest minimalna i można łatwo prześledzić wszystkie wartości adresów i rejestrów. Generalnie przełączanie jest oparte o SysTick.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wszystko wygląda ok, wszystkie wartości zapisują się prawidłowo, MSP również się przestawia na odpowiednią wartość, dlaczego więc wykrzacza się na ostatniej instruckji: asm("POP {R4-R11}") ? Zamiast __get_MSP i __set_MSP próbowałem też funkcji zaimplementowanych w przykładzie, ale one w ogóle przyjmują jakieś dziwne wartości i nic nie zmieniają (nic się nie przełącza):

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #10 30 Sty 2014 13:05
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Ten przykład jest dla czegoś innego niż Cortex-M3. Po pierwsze nie powinieneś używać push/pop, tylko "ręcznego" odkładania na PSP, bo push odkłada na stos PRZERWAŃ, a nie wątku. Po drugie nie powinieneś zapisywać i odtwarzać MSP, tylko PSP.

    4\/3!!

    0
  • #11 30 Sty 2014 13:24
    cabadath
    Poziom 6  

    Jest dla cortexa-M3: http://pastebin.com/Wsm7xeLM stąd go wziąłem, jeszcze spróbuję z PSP.

    Cytat:
    PUSH and POP are synonyms for STMDB and LDM (or LDMIA) with the memory addresses for the access based on SP, and with the final address for the access written back to the SP.
    ze strony http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/BABEFCIB.html

    Jakie, w takim razie, instrukcje masz na myśli?

    0
  • #12 10 Lut 2014 09:13
    djmdp
    Poziom 16  

    Tak skromnie zapytam - dlaczego nie użyjesz gotowego OS'a? Chociażby FreeRTOS'a ??

    0
  • #13 25 Lut 2014 11:39
    cabadath
    Poziom 6  

    Ponieważ zainteresowało mnie to i chciałbym się tego nauczyć.

    0
  Szukaj w 5mln produktów