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.

[stm32] freeRTOS zawieszanie się RTOSa

fazolek 18 Mar 2011 08:47 6480 33
  • #1 18 Mar 2011 08:47
    fazolek
    Poziom 12  

    Witam,
    mam problem z zawieszaniem się freeRTOSa. Program grzęźnie w funkcji vListInsert

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Sens jest mniej więcej taki:
    w tasku 2 wysyłam ramkę przez usart3, task 1 służy do odbioru odpowiedzi po odebraniu ramki ustawiana jest flaga RS485_flag. Flaga ta testowana jest w tasku 2 i w sytuacji kiedy zostanie ustawiona do tablicy dane[] zostanie przepisana odpowiedź.
    Program działa raz dłużej raz krócej ale zawsze ląduje w vListInsert.

    No i jeszcze obsługa przerwania:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Oba taski mają ten sam priorytet.

    Nie bardzo wiem gdzie szukać błędu. Zmienna [code]rozmiar[/code] przedstawiająca wielkość sterty jest różna od zera co moim zdaniem świadczy o fakcie, że nie doszło do przepełnienia sterty.
    Może ktoś z was spotkał się z takim problemem ??? nigdzie też nie korzystam z krytycznych obszarów freeRTOSa a ustawienia w freeRTOSConfig.h są zerżnięte z jakiegoś demka.

    0 29
  • CControls
  • #2 18 Mar 2011 11:38
    arrevalk
    Poziom 25  

    Po utworzeniu semafora wywołanie SemaphoreTake zawsze zwraca pdTRUE, nawet jeżeli nie została wywołana funkcja SemaphoreGive. W związku z tym zaraz po utworzeniu należało by go "wziąć"(oczywiście trzeba to wykonać przed włączeniem taska/przerwania które coś sygnalizuje tym semaforem). Problem ten pojawiał się jakiś czas temu na portach STM32 oraz SAM7S nie wiem czy został usunięty.

    0
  • #3 18 Mar 2011 12:32
    fazolek
    Poziom 12  

    Przed inicjalizacją tasków inicjalizuje semafory :

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    W/g tego co piszesz to po utworzeniu semafora binarnego muszę go pobrać ale w przypadku mutexa rozumie, że już go nie pobieram ?

    0
  • #4 09 Mar 2013 10:27
    Smashing
    Poziom 20  

    Witam
    wiem że stary temat ale poradziłeś sobie z nim, ja ma ten sam problem na stm32F2. (Program grzęźnie w funkcji vListInsert )
    Problem jest jak używam Can
    Jak jestem w przerwaniu i robię tak to działa:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Jak dam tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    To nie działa, co dziwne na USB nie ma problemów jak dam xQueueSendFromISR.
    Czy jak używam przerwań na FreeRtos to funkcja powinna mieć naked+ interrupt, czy tylko interrupt tak jak tu:
    Kod: c_loadrunner
    Zaloguj się, aby zobaczyć kod

    Chyba że to nie w tym problem... bo usb działa

    Pozdrawiam

    0
  • CControls
  • #5 09 Mar 2013 10:39
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    Jak jestem w przerwaniu i robię tak to działa:

    Większość funkcji FreeRTOSa zwraca jakiś kod błędu, wystarczy go sprawdzić a nie ignorować.

    Smashing napisał:
    Czy jak używam przerwań na FreeRtos to funkcja powinna mieć naked+ interrupt, czy tylko interrupt tak jak tu:

    W pliku FreeRTOSConfig.h po prostu dorzuć coś takiego:

    Kod: C
    Zaloguj się, aby zobaczyć kod

    (nazwy muszą się zgadzać z tymi z tablicy wektorów)

    4\/3!!

    0
  • #6 09 Mar 2013 10:58
    Smashing
    Poziom 20  

    Witam
    Freddie to mam dodane i cały system mi działa, problem jest tylko z CAN i jak w przerwaniu od Can daje xQueueSendFromISR to zaczynają się dziać "dziwne rzeczy"
    ja dam tak to działa

    Kod: c
    Zaloguj się, aby zobaczyć kod
    a po za komentowaniu:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    i dodaniu
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Jestem w przerwaniu to powinno być ok, a program grzęźnie w funkcji vListInsert.
    Pytanie czy jak mam void CAN1_RX0_IRQHandler (void) to dodać tam interrupt?
    Kod: c
    Zaloguj się, aby zobaczyć kod

    bo jak używam Usb w FreeRtos to mam tak i działa:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    i jak daje w Usb xQueueSendFromISR to nie ma żadnych problemów...

    0
  • #7 09 Mar 2013 11:17
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Generalnie lepiej dać "__attribute__ ((interrupt));"

    Jak masz problem w przerwaniu, to może masz po prostu za mało stosu dla tegoż przerwania (albo któregoś taska).

    4\/3!!

    0
  • #8 09 Mar 2013 11:49
    Smashing
    Poziom 20  

    Witam, sprawdzę wieczorem ale pewnie będzie problem z __attribute__ ((interrupt)) bo teraz jak to dodałem to kod się zmienił (3 linijki w asemblerze na początku i 2 na końcu funkcji ).
    xQueueSendFromISR dodatkowo używa portSET_INTERRUPT_MASK_FROM_ISR i portCLEAR_INTERRUPT_MASK_FROM_ISR tak samo jak SysTick_Handler, a on ma __attribute__ ((interrupt))
    Co do stosu to w skrypcie linkera mam ustawione na 1024...

    Pozdrawiam

    0
  • #9 09 Mar 2013 12:29
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    Witam, sprawdzę wieczorem ale pewnie będzie problem z __attribute__ ((interrupt)) bo teraz jak to dodałem to kod się zmienił (3 linijki w asemblerze na początku i 2 na końcu funkcji ).

    No ale po co byłoby dodawać atrybut który niczego nie zmienia? To chyba oczywiste, że COŚ się zmienić musi...

    Smashing napisał:
    Co do stosu to w skrypcie linkera mam ustawione na 1024...

    Co wcale nie znaczy, że jest to wartość wystarczająca, poza tym chodzi o stos dla PRZERWAŃ. Za mały może być też stos dla tasków i tylko przypadkiem problem "objawia" się jako związany z CANem.

    4\/3!!

    0
  • #10 09 Mar 2013 13:23
    Smashing
    Poziom 20  

    Witam
    Wiem że o __attribute__ ((interrupt)) jest dużo napisane na tym forum, i w sumie jak teraz patrzę na FreeRtos to oryginalnie jest tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    I wszystko działa... jakoś, xPortSysTickHandler jest na (void). Zamienię to teraz na :
    Kod: c
    Zaloguj się, aby zobaczyć kod
    lub pewnie ładniej by było:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Zwiększę na testy stos, ale nie chcę zmieniać czegoś czego nie jestem pewien
    Każdy Task w FreeRtos ma swój stos, podaję go jak tworzę task,
    Jeśli chodzi o przerwaniowy to jest jeden na wszystkie przerwania? czyli __process_stack_size.
    W FreeRtos __main_stack_size jest tylko do momentu jak nie uruchomię vPortStartFirstTask a potem biorę już stack z tego jak tworzyłem task (i jest osobny dla każdego tasku to oczywiste)
    Tak myślę to niech ktoś mnie poprawi jak się mylę...

    0
  • #11 09 Mar 2013 14:03
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    lub pewnie ładniej by było:

    ładniej by było tak jak napisałem na początku - 3 definicje. I nic nie obchodzi Cię czy ma być naked, interrupt czy może obydwa (albo żaden).

    Smashing napisał:
    Każdy Task w FreeRtos ma swój stos, podaję go jak tworzę task,

    A skąd pewność, że rozmiary które podajesz nie są za małe? Sprawdzałeś?

    4\/3!!

    0
  • #12 09 Mar 2013 14:36
    Smashing
    Poziom 20  

    Witam

    Freddie Chopin napisał:
    ładniej by było tak jak napisałem na początku - 3 definicje. I nic nie obchodzi Cię czy ma być naked, interrupt czy może obydwa (albo żaden).
    Jak wyrzuciłem:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    To kod w asemblerze jest jeszcze inny.
    Co to stosu jak testuje funkcje ustawiam "przewymiarowane". Jak zaczynam zjeżdżać stosem w dół uruchamia się vApplicationStackOverflowHook. Prosty mechanizm a miarę działa.
    Zrobiłem tak jak radzisz zobaczę wieczorkiem jak to działa.

    Pozdrawiam

    0
  • #13 09 Mar 2013 14:48
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    Jak wyrzuciłem:
    ...
    To kod w asemblerze jest jeszcze inny.

    Na pewno będzie inny, ale używając tylko definicji na pewno jest taki jak trzeba, bo Ty wtedy nie dokładasz żadnych dodatkowych atrybutów, tylko wskazujesz o które wektory przerwań chodzi, a reszta to już sprawa FreeRTOSa.

    4\/3!!

    0
  • #14 09 Mar 2013 15:19
    kaczor90
    Poziom 13  

    Witam. Nie chcąc zakładać nowego tematu zapytam tutaj, bo również problem dotyczy freeRTOS'a. Mam pytanie odnośnie tego, które funkcje w funkcji main są konieczne , aby RTOS mógł zacząć pracować. W demie funkcja main wygląda jak poniżej. Oczywiście prvSetupHardware i vTaskStartScheduler wiem, ale co do większości z nich nie mam pojęcia. Prosiłbym ewentualnie o słowo komentarza do tych "koniecznych" funkcji, lub link - odnośnik do wiedzy:) Pozdrawiam

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #15 09 Mar 2013 15:21
    Freddie Chopin
    Specjalista - Mikrokontrolery
  • #16 09 Mar 2013 15:48
    kaczor90
    Poziom 13  

    Dzięki. Program mi się wiesza na prvStartFirstTask(); na instrukcji svc 0

    Kod: c
    Zaloguj się, aby zobaczyć kod


    NVIC trzeba jakoś skonfigurować? Chodzi mi o ten rejestr - Vector table offset register (SCB_VTOR). Dodam to co chcę uruchomić.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #17 09 Mar 2013 16:04
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie masz "dopiętych" funkcji FreeRTOSa pod trzy przerwania systemowe. Cały temat powyżej jest praktycznie tylko o tym...

    4\/3!!

    0
  • #18 09 Mar 2013 18:47
    Smashing
    Poziom 20  

    Witam

    Zwiększenie stosu na przerwania rozwiązało sprawę (który to już raz....)
    Jeśli chodzi o sprawę __attribute__ musiałem to zostawić tak jak było w port.c czyli

    Kod: c
    Zaloguj się, aby zobaczyć kod
    bo FreeRtos się nie uruchamiał wcale (HardFault)jak to zakomentowałem.

    Dzięki,
    Pozdrawiam

    0
  • #19 09 Mar 2013 19:26
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    Jeśli chodzi o sprawę __attribute__ musiałem to zostawić tak jak było w port.c czyli
    Kod C - [rozwiń]
    void xPortPendSVHandler( void ) __attribute__ (( naked ));
    void xPortSysTickHandler( void );
    void vPortSVCHandler( void ) __attribute__ (( naked ));
    bo FreeRtos się nie uruchamiał wcale (HardFault)jak to zakomentowałem.

    Bez obrazy, ale już 3x napisałem, żebyś właśnie NIE ruszał ŻADNYCH plików FreeRTOSa, tylko do FreeRTOSConfig.h dodał 3 definicje DOKŁADNIE tak jak je wkleiłem, a Ty dalej kombinacje i modyfikacje atrybutów...

    Założenie pierwsze - nie dotykasz NIGDY żadnego pliku FreeRTOSa - NIGDY
    Założenie drugie - "dopięcie" przerwań do FreeRTOSa załatwiasz przez 3 definicje w pliku konfiguracyjnym

    Niektórzy naprawdę uwielbiają komplikować sprawy banalne. Mam u siebie kilka projektów zrobionych wg tego schematu i działa ZAWSZE. Nie ma prostszej, "czystszej", bardziej uniwersalnej czy bardziej przenośnej metody.

    4\/3!!

    0
  • #20 10 Mar 2013 01:31
    Smashing
    Poziom 20  

    Witam,
    Myślałem że po kłopocie ale jednak nie. Jestem dalej w tym samym punkcie.
    Program się "wiesza" na funkcji vListInsert.
    W tym momencie używam FreeRtos takiego jak od.... 4 lat czyli bez zmiany niczego w port.c. Jak zmieniam stos program czasem działa dłużej, czasem nie. Na testy mam tylko FreeRtos i CAN na 500kb
    Obecnie testy z działającym przerwaniem od CAN trwają już 3 godz. Zmieniłem tylko odbiór danych z :

    Kod: c
    Zaloguj się, aby zobaczyć kod

    na obecnie który działa od 3 godz
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Na tym pierwszym nie działa nawet 10 min. Jak program sie zawiesi to źrodłem zawieszenia jest if (xQueueReceive( xRxCanData, &m, portMAX_DELAY )==pdPASS)
    Zmieniłem teraz na kod if (xQueueReceive( xRxCanData, &m, portMAX_DELAY )==pdPASS).... 4 min i zwiecha. Stosy to już robię po 8kilo, nie wpływa to na częstotliwość zwiech, a na USB jest OK. Przetestuje przez cała noc z drugim wariantem... ręce opadają. Mam nadzieje że rano też będzie działać...
    Nie rozumie tego wpisu:
    arrevalk napisał:
    Problem ten pojawiał się jakiś czas temu na portach STM32 oraz SAM7S nie wiem czy został usunięty.

    Pozdrawiam

    0
  • #21 10 Mar 2013 08:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Smashing napisał:
    W tym momencie używam FreeRtos takiego jak od.... 4 lat

    Chodzi o "tak starą wersję"? (; Bo jeśli masz jakąś starą, to zawsze warto użyć nowszej...

    Skoro stosy masz duże, to można spokojnie przejść do drugiej najpopularniejszej przyczyny problemów - coś (np. DMA albo zwykły kod) wpisuje dane do bufora który nie istnieje lub poza bufor, przez co nadpisywana jest zawartość zmiennych FreeRTOSa. Jeśli masz debugger i wiesz o jaką zmienną chodzi, to mógłbyś ustawić sobie watchpointa, ale pewnie nie wiesz o którą zmienną FreeRTOSa się rozchodzi /;

    4\/3!!

    0
  • #22 10 Mar 2013 10:28
    Smashing
    Poziom 20  

    Witam
    FreeRTOSV6.1.1, taki od czerech lat to znaczy w źrodłach Rtos nic nie zmieniam, dodaje tylko w FreeRTOSConfig.h,

    Kod: c
    Zaloguj się, aby zobaczyć kod
    teraz jest chyba FreeRTOSV7.4.0 jeszcze to zmienię i zobaczę
    po całej nocy z druga wersja, czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    działa cały czas, 10 min temu zrobiłem 1 wersje i przed chwilą zwiecha.

    Na nowym było to samo....
    Poszedłem tropem ze Rtos musi być dobry.
    Zakomentowałem całą moją funkcję do "czytania danych", program się nie wieszał.
    Wstyd się przyznać ale na jednym memcpy nie miałem ochrony sekcji krytycznej. Testy robiłem wczoraj i zostawiłem na cała noc i jest ok.
    Bez komentarza.....

    0
  • #23 11 Mar 2013 17:09
    kaczor90
    Poziom 13  

    Freddie Chopin napisał:
    Nie masz "dopiętych" funkcji FreeRTOSa pod trzy przerwania systemowe. Cały temat powyżej jest praktycznie tylko o tym...

    4\/3!!


    Jeśli chodzi o te definicję w pliku FreeRTOSConfig.h to mam je tam umieszczone
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Niestety to chyba nie wszystko. Program mi się zawiesza tak jak pisałem wyżej.
    O coś innego niż te makra tutaj chodzi? Pozdrawiam

    0
  • #24 11 Mar 2013 17:22
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Możemy się kłócić, a ja wiem że masz je niepodpięte - te definicje które wrzuciłeś, to są NUMERY przerwań, a nie nazwy funkcji... w 5 poście jest prawidłowy fragment (prawidłowy dla STM32, u Ciebie przerwanie SVC ma inną nazwę niż "standardowa" dla STM32), możesz się upierać przy swoim, ja jednak jestem PEWNY, że problem jest właśnie w tym. Zobacz sobie co masz w tablicy wektorów, "SVCall_IRQn" czy może "SVC_Handler"...

    4\/3!!

    0
  • #25 11 Mar 2013 18:53
    kaczor90
    Poziom 13  

    Wcale nie mam zamiaru się kłócić:) Nie po to piszę żeby się kłócić, tylko poprosić o jakąś pomoc, wskazówkę, radę... Dzięki i zaraz popatrzę co tam zrobić, to co napisałeś.

    Dodano po 33 [minuty]:

    Hmm... no tak zmieniłem te definicje na to co zamieściłeś w poście 5. Dodam, że wcześniej miałem właśnie je, a że nie działało to przyszło mi do głowy, że może właśnie powinienem zmienić te makra. No w każdym razie program mi nie działa... Demo przerobione pod moje piny działa, a tu czegoś mi nadal brakuje. Jakieś sugestie?

    0
  • #26 11 Mar 2013 19:40
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Freddie Chopin napisał:
    (prawidłowy dla STM32, u Ciebie przerwanie SVC ma inną nazwę niż "standardowa" dla STM32)


    kaczor90 napisał:
    SVC_Handler


    Freddie Chopin napisał:
    SVCall_Handler


    4\/3!!

    0
  • #27 12 Mar 2013 10:40
    kaczor90
    Poziom 13  

    Dzięki wielkie! Takie szczegóły, a wszystko może przez nie nie działać. Teraz działa :)

    0
  • #28 23 Mar 2013 16:29
    Smashing
    Poziom 20  

    Witam
    Jednak problem jest nadal.... idę teraz w konfiguracje przerwań.
    w FreeRTOSConfig.h

    Kod: c
    Zaloguj się, aby zobaczyć kod
    Z tego co patrzyłem na inne przykłady to się odnosi do PreemptionPriority, czyli jak chcę ustawić na 15 to wtedy z automatu mam SubPriority =0 i jestem w NVIC_PriorityGroup_4 ? konfiguruje to tak?
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Tylko po co w przykładach też konfigurują:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Myślałem że to konfiguruje się "samo" jak ustawię
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Ano nie.... bo mogę być mieć SubPriority =0 i PreemptionPriority =0 i być w różnych grupach upss..
    Po dalszym zastanowieniu się dochodzę do wniosku że wiem że nic nie wiem :
    bo jak chcę ustawić np SubPriority =1 i PreemptionPriority =2 w grupie 3
    to mam 3 bity na Preemption i jednen bit na SubPriority robię tak?:
    Kod: c
    Zaloguj się, aby zobaczyć kod



    Jak wezmę moją "ukochaną" bibliotekę z stm32 to "oni" (w pliku misc.c) czytają
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Nawet jak ustawie
    Kod: c
    Zaloguj się, aby zobaczyć kod
    to tmppriority = 3
    dla // NVIC_IRQChannelPreemptionPriority =15 NVIC_IRQChannelSubPriority =0;
    Przy ich zapisie do NVIC->IP wpisują 30<<4 bo odczytują tmppriority = 3
    a przy moim do NVIC->IP wpisuje 15<<4 bo zakładam że NVIC_SetPriorityGrouping(4); działa
    hmmm....

    0
  • #29 23 Mar 2013 21:26
    Freddie Chopin
    Specjalista - Mikrokontrolery

    We wszystkich projektach które zrobiłem z FreeRTOSem NIGDY nie dotykałem Priority Group i zawsze działa [; Tyle że u mnie są np. takie ustawienia:

    Code:

    /* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
    (lowest) to 0 (1?) (highest). */
    #define configKERNEL_INTERRUPT_PRIORITY       255
    #define configMAX_SYSCALL_INTERRUPT_PRIORITY    191 /* equivalent to 0xb0, or priority 11. */

    /* This is the value being used as per the ST library which permits 16
    priority values, 0 to 15.  This must correspond to the
    configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
    NVIC value of 255. */
    #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY   15


    4\/3!!

    0
  • #30 23 Mar 2013 21:36
    Smashing
    Poziom 20  

    Witam
    A jak używasz przerwań np od RS232 to robisz tylko:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    bo w tych przykładach od z FreeRtos dodają jeszcze te opcje o których piszę i gróry.
    Używam obecnie przewiań od USB, Can, RS232, DMA, problem jest tyko z CAN, nawet jak tamte powyłączam i zostawię tylko CAN'a. Znalazłem podobny problem na stronie FreeRtos (też z CAN+stm32) ale nic z tego nie wynika
    Kiedyś z tym walczyłem i opuściłem... zostawiłem can bez przerwań sprawdzałem co 1ms czy są dane, tak mi to działa bez problemów przez kilka miesięcy.
    Zmieniłem te przerwania jak u Ciebie... teraz testuje

    0