Chciałem ostatnio popchnąć trochę do przodu jeden ze swoich poprzednich projektów - sprzętowe radio internetowe o którym pisałem już wcześniej, tylko tym razem w wersji ze zaktualizowaną częścią hardware'ową. Poprzednia wersja była tworzona na PIC32, teraz powoli chciałem przenieść go na STM32.
Większość softu właściwie już przeniosłem, teraz zostało najważniejsze - przeportowanie samej aplikacji odpowiedzialnej za odtwarzanie streamu z Internetu. W przypadku biblioteki MLA na PIC32 było to relatywnie proste. Socket sieciowy dysponuje buforem FIFO o zdefiniowanej pojemności - do niego trafiają dane przychodzące z serwera. Dane te pobieram i ładuję do bufora audio. Robię to jednak dopiero wtedy, gdy sterownik układu VS1003 stwierdzi, że dane są potrzebne.
W przypadku PIC32 było to relatywnie proste. Miałem kilka funkcji:
- TCPIsGetReady() - zwracała liczbę bajtów w buforze
- TCPGetArray() - funkcja zapisywała pod podany adres w pamięci określoną maksymalną liczbę bajtów z bufora. Zwracała liczbę bajtów, które w rzeczywistości udało się pobrać.
Sprawa była prosta - wystarczyło albo pobrać wszystkie dostępne dane, ale (jeśli było ich za dużo) tylko tyle, żeby wypełnić dostępne miejsce. W tym drugim przypadku nadwyżka pozostawała w buforze gniazda sieciowego i była sukcesywnie uzupełniania o kolejne przychodzące dane, które mogłem pobrać wtedy, gdy znów były potrzebne.
Widzę, że w przypadku lwIP (RAW API) sprawa nie jest już tak prosta. Zamiast tego muszę zarejestrować callback, który jest wołany za każdym razem, gdy przyjdą nowe dane. Callback otrzymuje w jednym z parametrów wskaźnik do struct ptr, w której mam m.in.
- void* paylod
- int len
- int tot_len
- struct pbuf* next
Istnieje więc możliwość, że wszystko co będę musiał zrobić to pobranie skopiowanie len bajtów spod adresu na który wskazuje payload. Istnieje jednak szansa, że danych jest więcej - wtedy tot_len > len i kolejnej porcji danych trzeba szukać w kolejnej strukturze, na którą wskazuje wskaźnik next.
Jeśli już zakończymy odczytywać dane, trzeba zawołać tcp_recved informując stos, że czekamy na kolejną paczkę. Tu jeszcze jest wszystko jasne.
Co jednak w sytuacji, gdy powiedzmy do zakończenia wypełniania bufora pozostało mi 100 bajtów, a w otrzymanej struct pbuf mam ich 500? Na PIC32 po prostu pobierałem 100, a reszta czekała na swoją kolej. W jaki sposób uzyskuje się podobny efekt na lwIP?