lwIP - odbieranie danych przez TCP

Sep 24, 2022 42 Replies

Wszystkie wersje tego urządzenia na PIC32 i MLA zawsze wyciągały wystarczającą szybkość, żeby być w stanie płynnie odtwarzać streamy z odległych serwerów. Przez odległe mam na myśli nawet studenckie rozgłośnie zza oceanu. ;)

Wczoraj udało mi się znaleźć źródło problemu. Okazało się ono być banalne, ale leżało w trochę nieoczekiwanym miejscu. Mianowicie prędkość SPI dedykowanego VS1003 była za mała. Nie wpadłem na to od razu, bo prędkość była w pełni wystarczająca aby odtwarzać nawet MP3 o większych bitrate'ach z lokalnych nośników. Problemem było to, w jaki sposób stos lwIP na RAW API dostarcza dane. W MLA można pobierać sobie dowolną ilość danych z bufora. W przypadku lwIP taka operacja jest możliwa jedynie przy użyciu socket API, które wymaga RTOS-a. Tutaj natomiast muszę albo:

- Przyjąć całą paczkę danych w callbacku odbiorczym, zwolnić pamięć i zgłosić gotowość przyjęcia kolejnej porcji.

- Opóźnić tę operację i wykonać ją trochę później w pętli głównej.

Nie po prostu zapisać w buforze tyle danych, ile aktualnie mam wolnego miejsca.

I tutaj problemem było tempo w jakim VS1003 by w stanie przyjmować dane. Zbyt często po prostu dochodziło do sytuacji, kiedy po przyjściu nowej paczki danych w buforze wciąż nie było dostatecznej ilości miejsca na jej przyjęcie i trzeba było czekać aż VS przeniesie je do swojego wewnętrznego bufora.

Po przyspieszeniu SPI wszystko zaczęło się odbywać dużo sprawniej. Okazało się jednak, że przy buforze cyklicznym umieszczonym w pamięci RAM (a więc ograniczonym do kilku kB) co jakiś czas zdarza się minimalne przycięcie. Po przywróceniu 128kB bufora w pamięci SPI RAM wszystko zaczęło działać zupełnie płynnie, chociaż na dobrą sprawę pewnie mógłbym jeszcze dość znacznie zmniejszyć rozmiar tego bufora.

Obecnie będę musiał jeszcze trochę zoptymalizować program, zwłaszcza pod kątem użycia pamięci. Może uda mi się jej trochę odzyskać po przywróceniu bardziej oszczędnych ustawień lwIP. Poza tym pingi nie wyglądają idealnie. Większość ma typową dla Ethernetu wartość 0.1-0.5 ms, jednak podczas odtwarzania streamu mniej więcej co piąty przychodzi z opóźnieniem od kilkudziesięciu do nawet ponad 100 ms. W przypadku wersji na PIC32 też były opóźnienia, ale nie aż tak duże.

Ale na moment zostawmy strumieniowanie. Czy robiłeś testy porównawcze transferu połączenia z internetu do "serwera" opartego na MLA w porównaniu do połączenia z tym samym (i do tej samej usługi) w lokalnym segmencie sieci? Interesuje mnie, czy to zjawisko jest tylko u mnie czy powszechne w takich małych stosach tcpip.

Zeby wywolac funkcje i przekazac bufor, to musi wiedziec, ze jakies dane przyszly. Czyli przerwanie.

A jak funkcja dlugo obsluguje ... moze przerwania sa wyłączone, dopóki nie skonczy.

I tu masz pare ryzyk: a) przy niewielkim buforze opoznienie w wyslaniu potwierdzenia moze skutkowac za duzym spowolnieniem transmisji,

b) bufory ci sie przepelniają, bo parametr TCP_window jest za duzy, i serwer na poczatku przysyla ci za duzo danych,

Dekoder karmiony w petli glownej? A moze tam sie zdarzaja duze opoznienia na inne akcje ?

A to juz moze byc, szczegolnie jesli widzisz, ze dociera kilka pakietow, a potem dluga przerwa ..

To drugie w zasadzie wyjasnia, ale oscyloskop i tak moze pomoc. Tu nawet nie oscyloskop, ale analizator logiczny za kilkadziesiąt zl.

TCP tak, pytanie, czy masz pelne TCP ..

Tak ogolnie TCP dziala tak, ze jak znikl jeden pakiet, to trzeba go retransmitowac. A po nim wysylane sa ponownie wszystkie nastepne.

Po otrzymaniu pakietu "niekolejnego", stos odbiorczy byc moze moze chwile poczekac - moze akurat "kolejny" przyjdzie, a nastepny juz czeka w buforze. Przy czym raczej nie podejrzewam, zeby niekolejne byly twoim problemem.

Nie znam, nie poradze.

J.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required