Skocz do zawartości

STM32F407 + FreeRTOS + lwIP + HTTPD - wejście na stronę zawiesza urządzenie


atlantis86

Pomocna odpowiedź

Jakiś czas temu złożyłem płytkę opartą na układzie STM32F107, zawierająca interfejs FastEthernet (na DP83848) oraz dekoder MP3 VS1003. Urządzenie w założeniu miało być odtwarzaczem plików muzycznych oraz streamów audio z Internetu. Po kilku początkowych próbach udało mi się na nim uruchomić oprogramowanie realizujące te zadania. Projekt opiera się na FreeRTOS-ie oraz lwIP. Cała konfiguracja została "wyklikana" w CubeMX. Oprogramowanie jest ciągle rozwijane, jednak podstawowa funkcjonalność działa. Mogę odtwarzać muzykę z nośników USB i kart SD oraz słuchać streamów HTTP z sieci. Działa także serwer HTTP, na razie udostępniający kolekcję statycznych stron, jednak docelowo ma tam być webowy interfejs użytkownika.

Dość szybko jednak okazało się, że obecny mikrokontroler jest nieco za mały na ten projekt. Użycie RAM-u w tej chwili dochodzi do 90%. Chociaż na razie nie wpływa to jeszcze na stabilność, to jednak stało się jasnym, że nie będę mógł wcisnąć zbyt wielu dodatkowych funkcjonalności i będę musiał uważać pisząc każdą kolejną linijkę kodu, aby przypadkiem nie zająć jeszcze więcej pamieci.

W kilka dni powstał więc projekt kolejnej płytki na STM32F407, którą wytrawiłem i zmontowałem w jeden weekend. Zacząłem od uruchomienia na niej podstawowego środowiska wyklikanego za pomocą STM32CubeMX. Dodawałem obsługę kolejnych peryferiów, które uruchamiały się bez problemu. Potem przeniosłem kod własnej aplikacji, która również ruszyła praktycznie od razu.

Pozostał jeszcze serwer HTTP. Kliknąłem odpowiednią opcję w STM32CubeMX, dodałem plik fsdata.c (zawierający skompresowany obraz prezentowanych stron) i w odpowiednim miejscu dodałem wywołanie funkcji httpd_init(0. Wszystko zupełnie tak, jak w oryginalnej wersji. Tym razem jednak po próbie wejścia przez przeglądarkę na adres IP urządzenia nie zobaczyłem oczekiwanej strony - zamiast tego płytka się zawiesiła. Przynajmniej tak to wyglądało z początku - moja aplikacja przestała działać, a płytka przestała odpowiadać na pingi.

Włączyłem więc debugger żeby sprawdzić, czy kod przypadkiem nie utknął w jakiejś nieskończonej pętli. Okazało się jednak, że FreeRTOS nadal działa. Spróbowałem więc dodać kilka printów w róznych miejscach.

Na chwilę obecną mam w tym projekcie dwa taski. Główny (priorytet "normal") odpowiada za działanie mojej aplikacji - odczytuje dane z nośników/Internetu i wysyła je do VS1003. Dodatkowo jest jeszcze task IoTask (priorytet idle), który docelowo będzie obsługiwał przyciski i wyświetlacz, ale na razie jest w nim tylko kilka wywołań funkcji wykonywanych w pętli zakończonej osDelay(20). Do tego oczywiście są jeszcze systemowe taski, obsługujące np. TCP/IP albo stos USB.

Okazało się, że próba wejścia na stronę powoduje zawieszenie cyklicznych printów z głównego tasku, jednak te z IoTask nadal są wykonywane.

Pierwszym wyjaśnieniem jakie przyszło mi do głowy był pomysł, że winę ponosi za mały rozmiar TOTAL_HEAP_SIZE, albo za mały rozmiar stosu w którymś z tasków. Te wartości są jednak albo takie same jak w oryginalnym projekcie, albo większe. W ramach eksperymentu próbowałem je zwiększać niemal dwukrotnie i nie przynosiło to żadnego rezultatu. Próbowałem też zwiększyć MEM_SIZE w ustawieniach lwIP z domyślnych 1600 bajtów do 10kB, ale w niczym to nie pomogło. Płytka wiesza się jeśli próbuję dostać się do serwera WWW, chociaż wszystko inne działa normalnie.

Ktoś ma pomysł co może być za to odpowiedzialne? Na razie poradzę sobie bez bez serwera WWW, ale jednak chciałbym mieć w tym projekcie interfejs webowy...

 

Update:

Zrobiłem mały eksperyment i spróbowałem wywołać tę awarię podczas odtwarzania z nośnika lokalnego (karta SD) zamiast sieci. Tym razem żaden z moich tasków się nie zatrzymał i odtwarzanie było kontynuowane, chociaż łączność sieciowa padła.

Można więc wyciągnąć z tego dwa wnioski:

  1. Próba dostanie się do serwera HTTP pracującego na tej płytce powoduje crash stosu lwIP, jednak bezpośrednio nie wywala RTOS-a ani żadnego z moim tasków.
  2. Za pierwszym razem główny task najwyraźniej blokował się na wywołaniach funkcji sieciowych, np. oczekiwał wiecznie na kolejną paczkę danych, które po wykrzaczeniu się stosu przestały przychodzić.
Edytowano przez atlantis86
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.