-
31. Data: 2022-10-02 15:11:58
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Marek <f...@f...com>
On Wed, 28 Sep 2022 13:06:14 +0200, Atlantis <m...@w...pl>
wrote:
> To jest właśnie plan na dalszą rozbudowę projektu. W wersji na
> PIC32
> było to trochę kłopotliwe, bo biblioteka TLS z MLA jest dość
> leciwa. Da
A czemu tak kurczowo się trzymasz MLA? Harmony też działa OK choć
troszkę na początku sprawia wrażenie bardziej skomplikowanego. Ale
jest bardzo podobny do MLA, nawet da się użyć uniwersalne wrapery by
projekt poszedł przezroczyście na mla/Harmony.
--
Marek
-
32. Data: 2022-10-02 21:06:11
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Atlantis <m...@w...pl>
On 2.10.2022 15:05, Marek wrote:
> Teraz mi się przypomniało, że miałem podobne problemy z tym projektem, z
> socket buf na spiram nawet 128kB (używany wewnętrznie przez stos MLA)
> powodował po pewnej chwili buffer underrun a o wiele mniejszy bufor
> aplikacyjny na dane (ale nie socket buffer) w ram mcu dawał spokojnie
> radę.
Jestem coraz mocniej przekonany, że winę za ten stan rzeczy może ponosić
zbyt mały rozmiar bufora odbiorczego gniazda sieciowego. W momencie gdy
aktualny pakiet jest przetwarzany (dane z niego są ładowane do pamięci
SPI) brakuje miejsca na przyjęcie kolejnego i wymuszana jest
retransmisja, powodująca w efekcie spowolnienie transmisji.
Przypomniałem sobie w międzyczasie, że bardzo podobny problem miałem na
prototypie tej konstrukcji, pracującej na PIC24FJ256DA210. Tam też nie
udało mi się uzyskać poprawnego odtwarzania streamów większych niż 32
kbps. Uznałem wtedy, że winę za to musi ponosić zbyt niskie taktowanie
magistrali SPI, na której pracuje ENC28J60. Wtedy się nad tym za bardzo
nie zastanawiałem, bo dysponowałem już nowsza wersją hardware'u. Jednak
teraz z perspektywy czasu wydało mi się to dziwne, bo w końcu 16 MHz to
nie mało.
Przypomniałem sobie także, że w tym projekcie na PIC24 także miałem
problemy z pamięcią. Układ ma co prawda 96kB RAM-u, jednak korzystanie z
niej nie jest takie oczywiste, bo tylko 32kB to dostępna bezpośrednio
pamięć, w której może znajdować się stos i sterta. Reszta to specjalna
pamięć stronnicowana, w której można umieszczać np. bufory ba dane.
Jednak z uwagi na to, że trzeba z nią postępować w odpowiedni sposób,
nie da się z niej bezpośrednio korzystać w standardowych bibliotekach.
W pewnym momencie zacząłem mieć problemy, które interpretowałem jako
nadpisywanie stosu. Pozmniejszałem więc rozmiary wszystkich buforów,
które musiały się mieścić głównej pamięci - w tym buforów odbiorczych
gniazd sieciowych.
Teraz przeprosiłem się z tym projektem na PIC24 i przyjrzałem mu się
bliżej. Po pierwsze wykorzystałem tę dodatkową pamięć (EDS) do
zaimplementowania 16kB bufora cyklicznego na dane audio. Już samo to
pozwoliło mi zaoszczędzić trochę głównej pamięci. Po drugie wczytałem
się trochę w opcje konfiguracyjne i zobaczyłem, że ten procesor ma
ustawieni o nazwie "Data model", które może przyjmować wartość "small"
lub "large". W "small" wszystkie zmienne statyczne oraz globalne muszą
zmieścić się w pierwszych 8kB RAM-u. W "large" nie ma tego ograniczenia.
Okazuje się, że to właśnie to ustawienie (a nie nadpisywanie stosu)
powodowało u mnie problemy. Okazało się więc, że tak naprawdę mam
jeszcze całkiem sporo "głównej" pamięci do zagospodarowania.
Pozwoliło mi to zwiększyć rozmiar bufora odbiorczego gniazda sieciowego
do ponad 6kB. To zdecydowanie poprawiło sytuację. Streamy 192kbps nadal
nie odtwarzają się poprawnie, ale te 128kbps i 160kbps już tak.
-
33. Data: 2022-10-02 21:41:48
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Mateusz Viste <m...@x...invalid>
2022-10-02 o 21:06 +0200, Atlantis napisał:
> Jestem coraz mocniej przekonany, że winę za ten stan rzeczy może
> ponosić zbyt mały rozmiar bufora odbiorczego gniazda sieciowego. W
> momencie gdy aktualny pakiet jest przetwarzany (dane z niego są
> ładowane do pamięci SPI) brakuje miejsca na przyjęcie kolejnego i
> wymuszana jest retransmisja, powodująca w efekcie spowolnienie
> transmisji.
To chyba niezupełnie tak - stack ogłasza raczej okienko nie większe,
niż rozmiar bufora gniazda, a zatem retransmisje z powodu "dostałem
pakiet ale nie miałem gdzie go zapisać" nie powinny mieć miejsca.
Oglądałeś połączenie pod jakimś wiresharkiem? Faktycznie widzisz tam
retransmisje?
Stawiałbym raczej na zbyt małe okienko, a więc i niewielką ilość
danych dostępnych z wyprzedzeniem, przez co jakikolwiek loss albo
chwilowe opóźnienie uniemożliwia dalsze odtwarzanie.
> Pozwoliło mi to zwiększyć rozmiar bufora odbiorczego gniazda
> sieciowego do ponad 6kB. To zdecydowanie poprawiło sytuację.
To zaledwie 4 pakiety. Wychodzi coś w okolicach 400ms dźwięku - malutko.
Mateusz
-
34. Data: 2022-10-04 09:04:02
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Atlantis <m...@w...pl>
On 2.10.2022 15:11, Marek wrote:
> A czemu tak kurczowo się trzymasz MLA? Harmony też działa OK choć
> troszkę na początku sprawia wrażenie bardziej skomplikowanego. Ale jest
> bardzo podobny do MLA, nawet da się użyć uniwersalne wrapery by projekt
> poszedł przezroczyście na mla/Harmony.
Po pierwsze kwestia czasu - mam kilka pootwieranych projektów, które
rozwijam niewielkimi krokami od kilku lat. To typowo hobbystyczne
projekty, więc wszystko zależy od tego, czy znajdę czas i motywację. A
jeśli już znajdę, to wolę go poświęcić na dodanie nowej funkcjonalności
niż przepisywanie istniejącego kodu pod nowe biblioteki.
Po drugie istniejące projekty są już na tyle rozbudowane, że mogę
traktować je jako podstawę do tworzenia kolejnych. Wszystko co ma
działać działa, jest dostępna bazowa funkcjonalność (np. konfiguracja
przez WWW), więc jeśli chcę stworzyć jakiś szybki projekt, to wystarczy
skopiować istniejący i zmodyfikować niektóre pliki. I to przedłużą życie
MLA w moich projektach.
Po trzecie - oryginalnie planowałem powolne przechodzenie na STM32 i
biblioteki HAL, więc uczenie się Harmony wydawało mi się nie mieć za
dużo sensu. Jednak koniec końców rozstanie się z PIC32 okazało się być
trudniejsze niż sądziłem i nie tylko kontynuuję istniejące projekty na
nich, ale też zdarzyło mi się zacząć kilka nowych, mniejszych.
-
35. Data: 2022-10-05 17:23:44
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Atlantis <m...@w...pl>
Ok, kompletnie nie mam pojęcia co może być powodem takiego zachowania
projektu. Wyczerpałem już chyba wszystkie pomysły. Na chwilę obecną
udało mi się sprawdzić następujące kwestie:
- Dodałem prosty kod do pomiaru ilości bajtów odbieranych w ciągu
sekundy. Dzięki temu mogłem ustalić, że zaraz po połączeniu z serwerem
nadającym stream mam transfer około 20 kB/s (co mniej-więcej pasuje do
bitrate'u 192 kbps), jednak zaraz potem spada on do 1-2 kB i zaczyna się
"czkawka". Bufor musi się przez dłuższą chwilę napełniać, żeby odtworzyć
krótki fragment audio.
- Zakomentowałem wszystkie operacje zapisu odebranych danych do pamięci
SPI RAM (w razie gdyby faktycznie to ona powodowała problemy). Po prostu
od razu zwalniam bufor z odebranymi danymi i zgłaszam gotowość do
odbierania kolejnych. I faktycznie - w tej sytuacji miałem ciągły
transfer w okolicach 20 kB/s.
- Już pomyślałem, że winę faktycznie ponosi pamięć SPI, przygotowałem
więc bufor cykliczny w zwykłej pamięci RAM. Implementacja nie jest może
idealna, ale sprawdziła się już w innym projekcie (na PIC24). Bufor jest
co prawda mały - testowałem wariant 4kB i 8kB - ale na wcześniejszych
wersjach hardware'u tych kilka kB w zupełności wystarczało do płynnego
odtwarzania. Niestety, po wgraniu tej wersji wrócił problem - prędkość
dość szybko spada do 1-2 kB.
- Żeby było ciekawiej zarówno 128kB bufor w pamięci SPI, jak i 8kB bufor
w zwykłym RAM-ie bez najmniejszego problemu sprawdzają się, gdy karmię
je danymi z karty SD. Wtedy odtwarzanie działa całkowicie normalnie.
Podejrzewam, że winę musi ponosić mój własny bład, którego jednak za nic
nie jestem w stanie namierzyć. Jeśli ktoś ma czas i ochotę żeby rzucić
okiem, to aktualna wersja jest dotępna na GitHubie:
https://github.com/marekw1986/InternetRadioSTM32/blo
b/main/code/Core/Src/vs1003.c
Kluczowe miejsca:
Callback obsługujący odbieranie przychodzących danych:
https://github.com/marekw1986/InternetRadioSTM32/blo
b/abb4f47bfd4c06ca0d56f6b03b287c5d4a4d9f3f/code/Core
/Src/vs1003.c#L869
Miejsce w maszynie stanów, gdzie ładowane są dane do bufora, ale bez
odtwarzania. Tutaj też realizowany jest opóźniony odbiór tych danych,
których nie dało się odebrać w callbacku z uwagi na brak miejsca w buforze:
https://github.com/marekw1986/InternetRadioSTM32/blo
b/abb4f47bfd4c06ca0d56f6b03b287c5d4a4d9f3f/code/Core
/Src/vs1003.c#L477
To samo co powyżej, tylko podczas normalnego odtwarzania:
https://github.com/marekw1986/InternetRadioSTM32/blo
b/abb4f47bfd4c06ca0d56f6b03b287c5d4a4d9f3f/code/Core
/Src/vs1003.c#L509
Miejsce w którym do bufora cyklicznego ładowane są dane z systemu plików
(karta SD lub pendrive):
https://github.com/marekw1986/InternetRadioSTM32/blo
b/abb4f47bfd4c06ca0d56f6b03b287c5d4a4d9f3f/code/Core
/Src/vs1003.c#L541
-
36. Data: 2022-10-05 18:37:06
Temat: Re: lwIP - odbieranie danych przez TCP
Od: a...@m...uni.wroc.pl
Atlantis <m...@w...pl> wrote:
> Ok, dopisa?em kilkana?cie linijek kodu odpowiedzialnego za mierzenie
> ilo?ci danych obieranych w serwera w ci?gu sekundy. Po prostu sumuj?
> ka?d? kolejn? warto?? p->tot_ten ze zmienn? tymczasow?, kt?ra co sekund?
> jest przepisywana do zmiennej trzymaj?cej aktualn? warto?? pomiaru a
> potem zerowana.
>
> Przeprowadzi?em dwa pomiary podczas odbierania streamu radiowej Jedynki.
> Pierwszy by? przy zakomentowanych operacjach zapisy do pami?ci SPI RAM.
> Wychodzi? transfer na poziomie 21-25 kB/s (czyli 168-200 kbps). Warto??
> zgodna z bitratem typowego strumienia audio.
> Natomiast po odkomentowaniu tych operacji warto?? spada do 5-11 kB/s
> (40-88 kbps) co t?umaczy przerywany d?wi?k.
> Nie wiem na ile to ma znaczenie, ale dodatkowo wida?, ?e w obydwu
> przypadkach na pocz?tku transmisja jest nieco szybsza i po kilku
> sekundach stabilizuje si? wok?? ni?szej warto?ci.
To by wskazywalo na zbyt male bufory/okno danych. Sprzet wyraznie
moze pracowac szybciej, ale kontrola przeplywu TCP mu nie pozwala.
Ja bym sprawdzil co sie dzieje jak wywalisz caly kod odpowiedzialny
za dzwiek i zostawisz tylko odbior strumienia, ale potwierdzajac
w takim tempie (w przyblizeniu) jak kodek by je odbieral.
Jeszcze moze glupie pytanie: w jakim tempie piszesz/czytasz ten
RAM SPI? DMA powinno przerzucac dane z maksymalna predkoscia
SPI, ale RAM moze miec porabany protokol a jak go obsluzysz
przez software to moga byc straty predkosci.
> Generalnie mo?na ju? wyci?gn?? kilka wniosk?w:
> 1. Mo?na ca?kowicie odrzuci? tez?, ?e win? za spowolnienia ponosi
> projekt p?ytki i gubienie pakiet?w z powodu b??d?w na warstwie
> sprz?towej (interfejs RMII). Gdyby tak by?o, to efekt by?by widoczny
> ca?y czas.
> 2. Operacja zapisu do pami?ci SPI RAM ma wp?yw na szybko?? transferu
> danych. Jednak nie jest to raczej prosta zale?no?? na zasadzie pami?ci
> maj?cej niewystarczaj?c? szybko??. Jak ju? m?wi?em - ten bufor
> ca?kowicie normalnie dzia?a z lokalnymi no?nikami, poza tym przy
> pr?dko?ci taktowania 18 MHz powinno by? mo?liwe przesy?anie danych ze
> znacznie wi?ksz? pr?dko?ci? ni? tych kilka kB/s. Poza tym problemy
> wyst?powa?y te? w przypadku stosowania (du?o mniejszego) bufora w
> normalnej pami?ci.
Pytanie kiedy potwierdzasz odbior: przed czy po zapisie do SPI
RAM. Jesli po to potwierdzenie jest opoznione i efektywnie
zmniejsza dostepne okno.
> Na chwil? obecn? stawia?bym raczej na moj? oryginaln? tez?: w czasie gdy
> program jest zaj?ty zapisywaniem oryginalnego pakietu, Ethernet nie jest
> w stanie odebra? nast?pnej porcji danych (bo ko?czy mu si? jaki?
> bufor/okno odbiorcze) i dochodzi do retransmisji, kt?ra spowalnia realn?
> pr?dko?? przesy?u danych.
Pisales ze jest 6kB na bufory LWIP. To 4 pakiety maksymalnej
wielkosci. Jesli 1 to wlasnie odbierany pakiet (nie wiem
czy LWIP ma na niego oddzielny bufor) a 1 to pakiet ktory
przerabiasz to zostaja 2 pakiety na buforowanie. Zaleznie
od szybkosci to moze byc 250-150 ms buforowania. Niby moze
dzialac ale ma prawo sie rwac.
Piszesz o jakims "buforze audio". Nie wiem co to ma byc,
ale datasheet VS1003 mowi o przesylaniu bloku 32 bajtow,
czyli w zasadzie jesli jest portrzebny jakis bufor to
na poziomie max setek bajtow. Czyli pownny byc dziesiatki
kilobajtow wolnej pamieci: STM32F107 ma 64KB RAM.
Moim zdaniem rozsadny projekt przydzielilby duzy kawalek
pamieci dla LWIP. Tak na oko minimum 15KB (10 pakietow
maksymalnej wielkosci). Przy 64KB RAM powinno byc
mozliwe przydzielnie LWIP 40KB (zwykle przyjmuje sie ze
implementacja TCP potrzebuje minimalnie 40KB do pracy,
ty masz jeden strumien a LWIP powinien byc oszczedny,
wiec moze bedzie dzialalo z mniejsza iloscia).
Przeplyw danych powiniem byc nastepujacy:
ETH -> bufor LWIP -> VS1003
Ewentualnie buforek powiedzmy 256 bajtow dla DMA pomiedzy
STM a VS1003 (taki buforek, podzielony na polowki po 128
bajtow wystarcza zeby DMA pracowalo plynnie).
> I teraz mam kilka pyta? co do tego, jak w?a?ciwie dzia?a Ethernet w STM32:
> Samo pobieranie danych z sieci do bufora odbiorczego jest realizowane w
> tle przez sprz?t, czy te? p?tla g??wna programu musi regularnie
> wywo?ywa? jaki? sterownik? To znaczy je?li bufor odbiorczy jest
> dostatecznie du?y, to dane b?d? nadal dochodzi?y nawet wtedy, je?li
> p?tla g??wna b?dzie zaj?ta czym? innym?
Ethernet ma swoje DMA ktore wrzuca pakiet do pamieci. Jak sie
dzieje cos co wymaga uwagi procka to zglasza przerwania.
Ten interfejs moze wrzucic dane do listy buforow (nie trzeba
jednego ciaglego bufora). Czyli jak sa dostepne bufory
to jest minimalne obciazenie procka. Ale kluczem jest
dostepnosc buforow. Nie wiem jak to rozwiazuje LWIP.
Jedna mozliwosc to kolejka buforow uzupelniana przez
petle glowna, wtedy procedura obslugi przerwania pobiera
bufory z kolejki (o ile sa dostepne). Ale mozna to
robic inaczej.
Jeszcze jedna uwaga: w STM transmisje danych powinno
robic DMA. "Dogladac" DMA powinny procedury obsugi
przerwan. Normalny kod powinien sledzic stan polaczenia
TCP, przygotowywac pakiety potwierdzenia (to robi LWIP)
i robic zarzadanie "wysokopoziomowe". Wiekszosc
operacji "petli glownej" powinna byc malo krytyczna
czasowo. Najwiecej uwagi moim zdaniem wymaga generowanie
potwierdzen (czyli wywolanie 'tcp_recved'), tak zeby
miec wlasciwa wielkosc okna TCP.
--
Waldek Hebisch
-
37. Data: 2022-10-06 09:47:27
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Atlantis <m...@w...pl>
On 05.10.2022 18:37, a...@m...uni.wroc.pl wrote:
> To by wskazywalo na zbyt male bufory/okno danych. Sprzet wyraznie
> moze pracowac szybciej, ale kontrola przeplywu TCP mu nie pozwala.
Które opcja w konfiguracji lwIP za to odpowiada? W stosie TCP/IP od
Microchipa po prostu ustawiało się parametr określający wielkość bufora
odbiorczego i nadawczego przy konfiguracji konkretnego socketu. W lwIP
nie widzę czegoś takiego niestety.
> Ja bym sprawdzil co sie dzieje jak wywalisz caly kod odpowiedzialny
> za dzwiek i zostawisz tylko odbior strumienia, ale potwierdzajac
> w takim tempie (w przyblizeniu) jak kodek by je odbieral.
Najbliższą rzeczą do tego jaką zrobiłem było wywalenie zapisywania
nadchodzących danych do bufora cyklicznego. I wygląda na to, że wtedy
leciały z maksymalną dostępną prędkością, odpowiadającą bitrate'owi
streama. Nie bardzo wiem natomiast jak w przypadku lwIP narzucić tempo
odpowiadające tempu zapotrzebowania na dane przez VS10xx. W przypadku
stosu od Microchipa było to proste - przychodzące dane trafiały do
bufora FIFO socketa, z którego mogłem je pobierać porcjami o dowolnej
wielkości. Jeśli dobrze rozumiem w przypadku lwIP i RAW API jest inaczej
- mam obowiązek przyjąć całą porcję danych zgłoszoną przez callback
odbiorczy, zwolnić pamięć i wywołać tcp_recved. Stąd potrzeba stosowania
bufora cyklicznego.
> Jeszcze moze glupie pytanie: w jakim tempie piszesz/czytasz ten
> RAM SPI? DMA powinno przerzucac dane z maksymalna predkoscia
> SPI, ale RAM moze miec porabany protokol a jak go obsluzysz
> przez software to moga byc straty predkosci.
Na chwilę obecną nie używam DMA - dane są po prostu przepisywane z
jednego miejsca w drugie w pętli. Myślałem, że SPI może powodować
opóźnienia, jednak tę hipotezę można już odrzucić ponieważ:
- Urządzenie zachowuje się identycznie w przypadku bufora cyklicznego w
ulokowanego pamięci SPI, jak również (mniejszego) w zwykłym RAM-ie.
- Żadne problemy nie występują w przypadku odtwarzania z karty SD.
> Pytanie kiedy potwierdzasz odbior: przed czy po zapisie do SPI
> RAM. Jesli po to potwierdzenie jest opoznione i efektywnie
> zmniejsza dostepne okno.
To tak można? ;) Myślałem, że tcp_recved() wolno mi wywołać dopiero po
przetworzeniu odebranych danych i zwolnieniu pamięci za pomocą pbuf_free().
> Pisales ze jest 6kB na bufory LWIP. To 4 pakiety maksymalnej
> wielkosci. Jesli 1 to wlasnie odbierany pakiet (nie wiem
6kB to chyba było odnośnie wcześniejszej wersji urządzenia,
zrealizowanej na PIC-u. Tam dość łatwo było ustawić konkretną wielkość
bufora odbiorczego.
> Piszesz o jakims "buforze audio". Nie wiem co to ma byc,
> ale datasheet VS1003 mowi o przesylaniu bloku 32 bajtow,
> czyli w zasadzie jesli jest portrzebny jakis bufor to
> na poziomie max setek bajtow. Czyli pownny byc dziesiatki
> kilobajtow wolnej pamieci: STM32F107 ma 64KB RAM.
Dodatkowy bufor na dane audio, pośredniczący w komunikacji pomiędzy
źródłem danych (Ethernet, lokalny nośnik pamięci) a VS10xx. Praktyka
pokazała, że jego zastosowanie dość mocno zwiększa stabilność, zwłaszcza
w przypadku Ethernetu. Implementowałem go do tej pory na jeden z dwóch
sposobów:
- klasyczny bufor cykliczny
- Dwuczęściowy bufor. Gdy jedna część karmi dekoder MP3, druga jest
ładowana danymi z zewnątrz. Potem następuje zamiana.
To właśnie tę funkcję w projekcie pełni pamięć SPI RAM.
-
38. Data: 2022-10-06 17:18:36
Temat: Re: lwIP - odbieranie danych przez TCP
Od: "J.F" <j...@p...onet.pl>
On Sun, 2 Oct 2022 09:39:10 +0200, Atlantis wrote:
> Ok, dopisałem kilkanaście linijek kodu odpowiedzialnego za mierzenie
> ilości danych obieranych w serwera w ciągu sekundy. Po prostu sumuję
> każdą kolejną wartość p->tot_ten ze zmienną tymczasową, która co sekundę
> jest przepisywana do zmiennej trzymającej aktualną wartość pomiaru a
> potem zerowana.
>
> Przeprowadziłem dwa pomiary podczas odbierania streamu radiowej Jedynki.
> Pierwszy był przy zakomentowanych operacjach zapisy do pamięci SPI RAM.
> Wychodził transfer na poziomie 21-25 kB/s (czyli 168-200 kbps). Wartość
> zgodna z bitratem typowego strumienia audio.
> Natomiast po odkomentowaniu tych operacji wartość spada do 5-11 kB/s
> (40-88 kbps) co tłumaczy przerywany dźwięk.
Ciekawe co na to serwer - nie moze ci wyslac danych odpowiednio
szybko, buforowac tez nie moze w nieskonczonosc - powinien gdzies u
siebie przeskakiwac na aktualne dane.
> Nie wiem na ile to ma znaczenie, ale dodatkowo widać, że w obydwu
> przypadkach na początku transmisja jest nieco szybsza i po kilku
> sekundach stabilizuje się wokół niższej wartości.
Ogolna zasada TCP - serwer wysyla na początku kilka pakietow danych,
dokladnie to TCP_window bajtow, a potem czeka na potwierdzenie
pierwszego.
W przypadku radia moze byc inaczej, jesli nie ma u siebie bufora
danych. No ale nawet wtedy te ~20kB/s szybko uzbiera, a Ty nie
nadążasz odebrac.
> Generalnie można już wyciągnąć kilka wniosków:
> 1. Można całkowicie odrzucić tezę, że winę za spowolnienia ponosi
> projekt płytki i gubienie pakietów z powodu błędów na warstwie
> sprzętowej (interfejs RMII). Gdyby tak było, to efekt byłby widoczny
> cały czas.
> 2. Operacja zapisu do pamięci SPI RAM ma wpływ na szybkość transferu
> danych. Jednak nie jest to raczej prosta zależność na zasadzie pamięci
> mającej niewystarczającą szybkość. Jak już mówiłem - ten bufor
> całkowicie normalnie działa z lokalnymi nośnikami, poza tym przy
> prędkości taktowania 18 MHz powinno być możliwe przesyłanie danych ze
> znacznie większą prędkością niż tych kilka kB/s. Poza tym problemy
> występowały też w przypadku stosowania (dużo mniejszego) bufora w
> normalnej pamięci.
>
> Na chwilę obecną stawiałbym raczej na moją oryginalną tezę: w czasie gdy
> program jest zajęty zapisywaniem oryginalnego pakietu, Ethernet nie jest
> w stanie odebrać następnej porcji danych (bo kończy mu się jakiś
Z grubsza mozliwe, ale patrz nizej.
A moze przerwania sa blokowane ?
> bufor/okno odbiorcze) i dochodzi do retransmisji, która spowalnia realną
> prędkość przesyłu danych.
Troche wątpie. Przy zgubieniu pakietu timeout sie wlacza, i to mogą
byc grube sekundy. Chyba bys nie uzyskal 5-11 kB/s.
No chyba, ze radio ma domyslnie jakies krotsze czasy.
Algorytm doboru timeoutu w TCP dosc skomplikowany ...
ale moze mozesz u siebie przetestowac - zasymuluj np zgubienie co
setnego pakietu.
Raczej bym sie spodziewal problemu w jakims opoznieniu w wyslaniu
potwierdzenia. Ale zeby az tak to SPI zwalniało? 18MHz wydaje sie
sporo ... a ogladales oscyloskopem? Albo czy mierzyles
przepustowosc/czas zapisu pakietu?
A w ogole ... masz tam jakies zabezpieczenie kolejnosci w tej
bibliotece? Bo powiedzmy przychodzą pakiety nr 1, 2, 3, a nr 4 nie
przychodzi. Ale przychodzi nr 5, 6, 7 ... i co wtedy - nie dostaniesz
callbacka z nr 5, a bufory 5, 6, 7 zostaną skasowane ?
Ba, bez zadnych retransmisji moga przyjsc pakiety w kolejnosci
1, 2, 3, 5, 4, 6, 8, 7, itp.
J.
-
39. Data: 2022-10-07 20:40:36
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Atlantis <m...@w...pl>
On 6.10.2022 17:18, J.F wrote:
> Ciekawe co na to serwer - nie moze ci wyslac danych odpowiednio
> szybko, buforowac tez nie moze w nieskonczonosc - powinien gdzies u
> siebie przeskakiwac na aktualne dane.
I wszystko wskazuje na to, że tak to właśnie działa. Przynajmniej
odnoszę wrażenie, że dźwięki które słyszę z przerwami nie są kolejnymi
fragmentami tego samego strumienia audio, ale raczej "okienkami" które
aktualnie udaje się odebrać.
> W przypadku radia moze byc inaczej, jesli nie ma u siebie bufora
> danych. No ale nawet wtedy te ~20kB/s szybko uzbiera, a Ty nie
> nadążasz odebrac.
Tak. Pytanie tylko dlaczego nie nadążam tego odebrać. Można było
teoretyzować o niskiej przepustowości pamięci SPI RAM (co i tak było
wątpliwe, bo 18 MHz to naprawdę szybka transmisja) ale ta teoria padła w
momencie, gdy identyczny problem udało się stwierdzić także w przypadku
zastosowania bufora cyklicznego w RAM-ie.
> Z grubsza mozliwe, ale patrz nizej.
> A moze przerwania sa blokowane ?
Jakie przerwania? W moim kodzie w ogóle nie używam przerwań związanych z
Ethernetem. Używam gotowych sterowników dostarczanych przez producenta
mikrokontrolera oraz gotowego stosu (lwIP). W rozsądnym projekcie
użytkownik nie powinien w ogóle przejmować się przerwaniami - powinny
one w tle ładować dane do jakiegoś FIFO. Zresztą nigdzie w dokumentacji
nie znalazłem ani jednej wzmianki o przerwaniach.
O ile informacje na jakie udało mi się trafić w Internecie są poprawne,
to procedura odbioru jest następująca:
- Stos wywołuje zarejestrowana wcześniej funkcję obsługi callbacku
odbiorczego.
- Do tej funkcji przekazywany jest wskaźnik na struct pbuf. Struktura
zawiera dynamicznie alokowany bufor na payload. Może też zawierać
wskaźniki do kolejnych struktur tego samego typu.
- Z jednej lub kilku struktur trzeba pobrać dane i gdzieś je zapisać.
- Jeśli już skończyliśmy tę operację, wywołujemy pbuf_free() aby zwolnić
pamięć oraz tcp_recved() aby zwiększyć rozmiar okna (poinformować
serwer, że może przesłać więcej).
U mnie może się zdarzyć sytuacja, że otrzymanych danych będzie więcej
niż miejsca w buforze. Wtedy nie mogę ich odebrać od razu - muszę się z
tym wstrzymać do czasu, aż dekoder MP3 wyjmie z bufora odpowiednią ilość
danych. Wtedy odbiór tej konkretnej paczki jest opóźniony i odbywa się w
pętli głównej.
W żadnym miejscu nie mam do czynienia z przerwaniami.
> Troche wątpie. Przy zgubieniu pakietu timeout sie wlacza, i to mogą
> byc grube sekundy. Chyba bys nie uzyskal 5-11 kB/s.
Kiedy transmisja zaczyna mulić to nie jest 5-11 kB/s, a 0-2kB/s.
> Raczej bym sie spodziewal problemu w jakims opoznieniu w wyslaniu
> potwierdzenia. Ale zeby az tak to SPI zwalniało? 18MHz wydaje sie
> sporo ... a ogladales oscyloskopem? Albo czy mierzyles
> przepustowosc/czas zapisu pakietu?
Nie, bo wydawało mi się to nie mieć sensu. Udało mi się ustalić, że wina
nie leży po stronie pamięci SPI. Przemawiają za tym dwa argumenty:
- Pamięć SPI doskonale sprawdza się przy buforowaniu streama z karty SD.
- Ten sam problem występuje, jeśli dane przychodzące przez TCP próbuję
zapisywać do bufora cyklicznego ulokowanego w zwykłym RAM-ie.
> A w ogole ... masz tam jakies zabezpieczenie kolejnosci w tej
> bibliotece? Bo powiedzmy przychodzą pakiety nr 1, 2, 3, a nr 4 nie
> przychodzi. Ale przychodzi nr 5, 6, 7 ... i co wtedy - nie dostaniesz
> callbacka z nr 5, a bufory 5, 6, 7 zostaną skasowane ?
Wydaje mi się, że przecież chyba TCP ogarnia kwestię pakietów
przychodzących w złej kolejności i użytkownik nie musi się przejmować tą
kwestią podczas pisania aplikacji. Ten problem pojawia się dopiero w
przypadku zastosowania UDP.
Tak czy inaczej lwIP ma opcję związana właśnie z tą kwestią. Jeśli
dobrze rozumiem to można wybrać jak ma się zachować stos. W przypadku
zgubienia któregoś z pakietów w sekwencji można albo trzymać nadmiarowe
do momentu otrzymania brakującego, albo poprosić jeszcze raz o wysłanie
całej sekwencji licząc, że tym razem przyjdą wszystkie i po kolei.
Próbowałem obydwu ustawień.
Swoją drogą, czy ktoś może mi wyjaśnić w jaki sposób skonfigurować lwIP,
żeby mieć dostatecznie duży bufor odbiorczy? W stosie od Microchipa po
prostu ustawiało się wielkość bufora nadawczego i odbiorczego dla
konkretnego gniazda. Tutaj cała masa opcji, które nic mi wprost nie mówią...
https://github.com/marekw1986/InternetRadioSTM32/blo
b/main/code/LWIP/Target/lwipopts.h
-
40. Data: 2022-10-09 08:25:05
Temat: Re: lwIP - odbieranie danych przez TCP
Od: Marek <f...@f...com>
On Sun, 2 Oct 2022 21:06:11 +0200, Atlantis <m...@w...pl>
wrote:
> Jestem coraz mocniej przekonany, że winę za ten stan rzeczy może
> ponosić
> zbyt mały rozmiar bufora odbiorczego gniazda sieciowego. W momencie
> gdy
> aktualny pakiet jest przetwarzany (dane z niego są ładowane do
> pamięci
> SPI) brakuje miejsca na przyjęcie kolejnego i wymuszana jest
> retransmisja, powodująca w efekcie spowolnienie transmisji.
A czy problemy z odtwarzaniem przez sieć nie wynikają ze słabej
wydajności stosu tcpip iwip/mla przy "odległych" podłączeniach? Np.
MLA szybko działa w lokalnej sieci (kilkaset kB/s) ale przez internet
jest już znacznie wolniejszy (kilka kB/s) niż oczekiwany wpływ
szybkości łącza. Problem rozwiązuje uzycie lokalnego proxy: gdy
łączymy się z internetu do mcu przez lokalne proxy np. raspi szybkość
pozostaje zachowana jak przy połączeniu lokalnym. Czy ktoś się
domyśla z czego to wynika?
Czy próbowałeś odtwarzać przez lokalne proxy? Odwrotna sytuacja niż
opisana wyżej. Uruchomić proxy do oryginalnego streamu na lokalnym
komputerze w tym samym segmencie sieci co jest player na iwip/mla i
niech ten player pobiera stream z proxy w lokalnej sieci a nie
bezpośrednio z urla z internetu.
--
Marek