Witam!
Od kilku dni produkuje tony kodu w C na AVR'ka.
Programuje urządzenie sieciowe oparte na Atmega32. Na pokładzie mam ENC28J60, 32kb SRAM i 128kB EEPROM.
Dylemat jest następujący: jak zorganizować dane w pamięciach RAM aby wszystko optymalnie chodziło.
Teraz używam 500B wewnętrznego RAM na bufor gdzie wczytuje cały pakiet sieciowy z ENC. Nie pozwala mi to na operowanie pełnymi pakietami sieciowymi tj. 1514B. W RAM AVR jest też miejsce na tablice portów gdzie przechowuje wskaźniki do funkcji aplikacji sieciowych i stan klient/serwer. Zewnętrzny RAM przechowuje tablice TCP, ARP i UDP. Są to wpisy na temat aktualnego stanu połączenia dla TCP i UDP a adresów IP i MAC dla ARP.
Bufor sieciowy musi być trzymany w RAM wewnętrznym, gdyż bardzo łatwo mi rzutować dane pakietu na wskaźnik struktury języka C (bardzo łatwo się wtedy operuje na danych). Myślałem natomiast o innym triku który wymaga ingerencji w sterownik enc28j60. Konkretnie, zamiast funkcji enc28j60ReceivePacket, która wczytuje cały pakiet z RAM karty sieciowej do wewnętrznego RAM, zastąpiłbym ją funkcją która wczytuje do bufora tylko 14B (tyle ile zajmuje nagłówek Ethernet). Dzięki temu mogę rozpoznać jakiego pakietu się spodziewam.
Kolejną funkcją byłaby taka która na podstawie danych z nagłówka Ethernet wczytuje dane IP/ARP. Tutaj znowu rozpoznanie kolejnych danych i wczytanie nagłówka ICMP/TCP/UDP.
Dane, natomiast byłyby wczytywane do zewnętrznego SRAM, pozwoliłoby to na operowanie na pakietach maksymalnej wielkości.
Kolejny pomysł ma się wysyłaniu pakietów. Nagłówki składane w RAM wewnętrznym, bez wyliczania sumy CRC, dlaczego, o tym później. Wysłane do ENC, wraz z danymi składowanymi w SRAM zewnętrznym.
I znów możliwość generowania pełnych pakietów 1514B.
Najważniejsza myśl z dziedziny szybkości działania to sumy CRC. Moja atmega z zegarem 12,5MHz (pobieranym z karty sieciowej) spędza mnóstwo czasu na generowaniu sumy kontrolnej. Trzeba odciążyć procesor.
Nie znalazłem w sieci projektu który korzystałby do generowania wbudowanego w ENC28J60 kontrolera DMA. Piekielnie szybkiego i niezawodnego.
Żeby tego dokonać trzeba znowu ingerować w funkcje wysyłania pakietów, enc28j60SendPacket, i po zapisaniu wszystkich danych w karcie sieciowej obliczyć sumy CRC i zapisać w odpowiednich komórkach pakietu.
To co tu opisałem oczywiście nie musi być poprawne, to tylko rozmyślania. Przed sprawdzeniem w praktyce chciałbym się poradzić czy to się opłaca i jak Wam się to widzi.
Nie lubię znacznie modyfikować działania programów które mają ponad 2000 linijek kodu i działają dosyć dobrze, dlatego chce mieć wszystko rozplanowane.
Oczywiście wszelkie inne propozycje mile widziane!
Peace for all!
Od kilku dni produkuje tony kodu w C na AVR'ka.
Programuje urządzenie sieciowe oparte na Atmega32. Na pokładzie mam ENC28J60, 32kb SRAM i 128kB EEPROM.
Dylemat jest następujący: jak zorganizować dane w pamięciach RAM aby wszystko optymalnie chodziło.
Teraz używam 500B wewnętrznego RAM na bufor gdzie wczytuje cały pakiet sieciowy z ENC. Nie pozwala mi to na operowanie pełnymi pakietami sieciowymi tj. 1514B. W RAM AVR jest też miejsce na tablice portów gdzie przechowuje wskaźniki do funkcji aplikacji sieciowych i stan klient/serwer. Zewnętrzny RAM przechowuje tablice TCP, ARP i UDP. Są to wpisy na temat aktualnego stanu połączenia dla TCP i UDP a adresów IP i MAC dla ARP.
Bufor sieciowy musi być trzymany w RAM wewnętrznym, gdyż bardzo łatwo mi rzutować dane pakietu na wskaźnik struktury języka C (bardzo łatwo się wtedy operuje na danych). Myślałem natomiast o innym triku który wymaga ingerencji w sterownik enc28j60. Konkretnie, zamiast funkcji enc28j60ReceivePacket, która wczytuje cały pakiet z RAM karty sieciowej do wewnętrznego RAM, zastąpiłbym ją funkcją która wczytuje do bufora tylko 14B (tyle ile zajmuje nagłówek Ethernet). Dzięki temu mogę rozpoznać jakiego pakietu się spodziewam.
Kolejną funkcją byłaby taka która na podstawie danych z nagłówka Ethernet wczytuje dane IP/ARP. Tutaj znowu rozpoznanie kolejnych danych i wczytanie nagłówka ICMP/TCP/UDP.
Dane, natomiast byłyby wczytywane do zewnętrznego SRAM, pozwoliłoby to na operowanie na pakietach maksymalnej wielkości.
Kolejny pomysł ma się wysyłaniu pakietów. Nagłówki składane w RAM wewnętrznym, bez wyliczania sumy CRC, dlaczego, o tym później. Wysłane do ENC, wraz z danymi składowanymi w SRAM zewnętrznym.
I znów możliwość generowania pełnych pakietów 1514B.
Najważniejsza myśl z dziedziny szybkości działania to sumy CRC. Moja atmega z zegarem 12,5MHz (pobieranym z karty sieciowej) spędza mnóstwo czasu na generowaniu sumy kontrolnej. Trzeba odciążyć procesor.
Nie znalazłem w sieci projektu który korzystałby do generowania wbudowanego w ENC28J60 kontrolera DMA. Piekielnie szybkiego i niezawodnego.
Żeby tego dokonać trzeba znowu ingerować w funkcje wysyłania pakietów, enc28j60SendPacket, i po zapisaniu wszystkich danych w karcie sieciowej obliczyć sumy CRC i zapisać w odpowiednich komórkach pakietu.
To co tu opisałem oczywiście nie musi być poprawne, to tylko rozmyślania. Przed sprawdzeniem w praktyce chciałbym się poradzić czy to się opłaca i jak Wam się to widzi.
Nie lubię znacznie modyfikować działania programów które mają ponad 2000 linijek kodu i działają dosyć dobrze, dlatego chce mieć wszystko rozplanowane.
Oczywiście wszelkie inne propozycje mile widziane!
Peace for all!