Komunikacja z pendrive USB, pic32 a konkurencja

Nov 04, 2013 10 Replies

Jakiś czas temu pytałem jakich prędkości mogę się spodziewać z pic32



  • mass storage, w końcu odpaliłem Microchipowe MSD i, że tak powiem, szału nie ma. Odczyt sektora (bez warstwy FS na razie) przy zegarze

40MHz odbywa się z prędkością ok 170kB/s. Jak to wychodzi u konkurencji, np. stm32 ? Oczywiście chodzi mi o w miarę porównywalne układy z pic32 a nie jakieś super "wypasione" army.
1MB/s uznałbym za wynik zadowalający...

Popatrz , co tam Ci kompilator wymyślił. Często jest to bezsensowna praca w pętli. Wystarczy ją namierzyć debuggerem i poprawić. Napisz w ASM (fragment lub całość) lub wybierz coś szybszego. Jednak może się okazać, że na dsPIC33 zadziała znacznie lepiej. Mam wrażenie, że kompilator nie radzi sobie w ogóle z kolejkowaniem instrukcji i danych w rdzeniu MIPS. Przez to powstają znaczące opóźnienia. Te 40MHz w 32MX to nie jest tak jak w dsPIC. S.

Chyba żartujesz :-) $ pic32mx-objdump -S -h -d --section=.text code.elf | egrep -c ^9d.*:

6560

6550 instrukcji asm, nie wiem ile miesięcy by zajęło zabawa w optymalizację tego na poziomie asm. Z tego co udało mi się dowiedzieć taki transfery są spowodowane cechami implementacji stosu usb Microchipa i niekoniecznie jedynym rozwiązaniem jest poprawianie kodu wynikowego asm.

Sugerujesz, że gcc-mips-4.5.2 jest "niedopracowany"? Brzmi to dość wyzywająco, szczególnie, że to już raczej dojrzała architektura i gcc raczej powinien dobrze sobie z nią radzić.

Nie jestem pewien, czy dokładnie 4.5.2, ale dokładnie tak uważam, gdyż oglądałem kod po kompilacji. Zresztą na każdym kroku piszą, że to użytkownik powinien wiedzieć, jak sterować kolejką i nie zakładać, że kompilator to zrobi najlepiej. Niestety nie powiem Ci gdzie to wyczytałem, ale jakoś tak to szło.

Przy czym ja podziękowałem za gcc i zrobiłem full in asm. Jeśli dobrze odczytuję raport, to czytego kodu w asm wyszło ok. 4kB. Reszta to obrazki.

Microchip PIC32 Memory-Usage Report

kseg0 Program-Memory Usage section address length [bytes] (dec) Description

------- ---------- ------------------------- ----------- .rodata 0x9d000008 0x69280 430720 Read-only const .text 0x9d069288 0xebc 3772 App's exec code .text.general_exception 0x9d06a144 0xd0 208 .text 0x9d06a214 0x28 40 App's exec code .dinit 0x9d06a23c 0x10 16 .text._general_exceptio 0x9d06a24c 0xc 12 .text._bootstrap_except 0x9d06a258 0xc 12 .text._on_reset 0x9d06a264 0x8 8 .text._on_bootstrap 0x9d06a26c 0x8 8 Total kseg0_program_mem used : 0x6a26c 434796 82.9% of

0x80000

A jakie optymalizacje miałeś włączone (-O)?

Nie manipulowałem przy opcjach kompilacji. Po prostu, zobaczyłem efekt przy domyślnych wartościach firmowego przykładu Microchipa (!!!) *.mpc i stwierdziłem, że skoro wypieszczony przykład nie działa, to co tam będę "grzebał śrubokrętem w Rubinie 714". Dodam, że projekt został rozpoczęty i ukończony w asm, spełniając moje oczekiwania bez zbędnych kompromisów, które będą z pewnością konieczne przy Twoim problemie. S.

Ale zdajesz sobie sprawę z złożoności problemu, który wymaga w moim przypadku implementacji następujących warstw:

- usb host

- mass storage już nie wspominam, że musi to być połączone z:

- filesystem driver (fat32)

- ethernet driver

- tcp/ip

Celem jest zamiana w działającym już projekcie karty sd, na pendrive bo jest wygodniejszy i zajmuje mniej pinów do komunikacji. I rozumiem, że Ty taki projekt zaczął byś w asm pisać zamiast pójść na kompromis i skorzystać z gotowego i przetestowanego softu?

Uruchomienie usb msd zajęło mi godzinkę: przeniesienie kodu potrzebnych driverów usb msd do drzewa projektu, korekta kilku linijek kodu usb msd aby dostosować je do współpracy z driverem fat, który używam zamiast tego, który używa msd Microchipa, mała korekta Makefile. Gdyby nawet te future drivey były tylko w asm zamiast w C, to włączenie ich w istniejący projekt na pewno zajęłoby więcej niż tą godzinę.

...

Wiesz dobrze, tak jak ja, ¿e czas jaki na to po¶wiêci³e¶, aby to uruchomiæ, by³ znacznie d³u¿szy. Sam± godzinkê, to mo¿e zajê³o Ci skompilowanie i dostosowanie. Droga opracowania projektu sk³ada siê z wielu dodatkowych kroków, które s± niezale¿ne od asm czy C np. instalacja MPLABA na nowszym komputerze, przeczytanie manuala do DevBoard'a, poszukanie, któr± procedurê musisz wywo³aæ, zrozumienie co autor mia³ na my¶li itp.

Jednak to co nastêpuje teraz, to faza wymiany hardware'u na konkurencjê (jak napisa³e¶). W zwi±zku z powy¿szym trochê tak uciekasz i ... znów kilka godzin.

Je¿eli Twój projekt wydaje Ci siê du¿y, to rozbij go na mniejsze. W szczególno¶ci mo¿esz u¿yæ np. dwóch procesorów z gotowym C-codem: a) do szybkiego internetu b) do obs³ugi karty SD Jednak to jest jeszcze wiêksza ucieczka.

Tak czy inaczej napisz do jakich prêdko¶ci doszed³e¶ i na czym, bo chyba nie zdecydujesz siê na asm.

Mia³em taki przypadek, gdzie by³a prosta pêtla w C na odczytywanie portu równoleg³ego i wysy³anie po Ethernecie. Ch³opak napisa³ to w C, u¿ywaj±c stosu Microchipa na 18Fxxxx Sama pêtla wysy³ania danych by³a prosta jak drut. Nalega³em, aby zobaczyæ gdzie biega w pêtli mikrokontroler. Wstawka zosta³a zrobiona w asm i transfer podskoczy³ kilkakrotnie. Czasem naprawdê niewiele potrzeba. S.

przeczytanie

Nie używam mplabl'a.

Nie używam jakiegoś konkretnego devboarda, płytka stykowa jedynie.

Projekt wydawałby mi się duży, gdyby był w asm, wręcz nie do ogarnięcia, jakbym miał co chwilę coś zmieniać, bo dłubać lubię :). W asm to byłby kompletny nonsens. W C całość jest czytelna, podzielona na poszczególne liby robiące konkretne rzeczy, spokojnie do ogranięcia jeśli uwzględnić stosunek liczby funkcji do objętości kodu, szczególnie przez takiego amatora jak ja.

Wąskie gardło jest w Microchipowej implementacji komend scsi read10 (write10), w jednej transakcji jest odczytywany tylko 1 blok 512 bajtów (bo pokrywa się to w większości przypadków z wielkością sektora), Każda transakcja idzie w określonej ramce czasowej usb, czytanie w jednej ramce tylko 512 jest tym wąskim gardłem. Jednym ze sposobów jest zwiększenie ilości bloków per trans. w read10, jak zwiększyłem liczbę bloków w read10 transfer skoczył do ~1 MB/s. Oczywiście aby to działo na poziome fs to taka manipulacja (zmiana wielkości sektora/liczby bloków per read) musi być uwzględniona w warstwie drivera fs. Drugi sposób oraz więcej info na ten temat można przeczytać tutaj:

formatting link
high=&m=524271&mpage=1#524504

Ładny rysunek gość załączył. Wiesz może z jakiego to analizatora? Tak czy inaczej problem jest szerszy. Opóźnienia są w wielu źródłach: a) procedury zapisu/odczytu USB b) overhead / stata czasu na obsługę zbędnego protokołu USB. Nie wiem, czy w trybie Bulk nie działałoby to lepiej. c) mało pamięci RAM d) pojęcie stosu -zupełnie nieadekwatne do naszych czasów. Wynika moim zdaniem, tylko z braku RAM. e) przekazywanie parametrów/ wzajemne wywoływanie procedór dla obsługi SD itp.

Złożenie tego w profesjonalną całość jest trudne. Wiedzą o tym producenci Smartfonów. Okazuje się, że taki smartfon ma 4 rdzenie. Linux działający na tym ma za zadanie zrobić zdjęcie, przesłać, pokazać. To to samo z filmem. Moja znajoma nosi takiego smartfona w tylniej kieszeni spodni. Bardzo sobie chwali, bo ma wszystko w jednym: telefon, zdjęcia, filmy, storage itp. Nie musi wozić ze sobą aparatu, albumów. Problem jest jednak inny. Wygląda na to, że jedynym rozwiązaniem w wykonaniu prostych rzeczy staje się rozbudowa programowa, polegająca na dodawaniu bibliotek i wypuszczaniu kolejnych wersji systemu z poprawkami. Realizację tego powierza się multiplikowanym procesorom, choć nie chodzi tu o wydajność matematyczną, tylko o szybkość przerzucania megabajtów instrukcji, aby dwoma palcami powiększyć zdjęcie. Dojdziemy do gigajtowych bibliotek wyświetlających ikonki (teraz widgety się to chyba nazywa. Kiedyś ghosty czy sprites?) na 256-bitowych procesorach zmultiplikowanych w postaci 2000 pinowego BGA (ups... też już nie pinowego, tylko plackowego?), który mieści w sobie 64 rdzenie. Lepiej już od razu ustalić, że PCB to będzie obudowa BGA, do której dokleja się baterię, głośnik, LCD i antenę.

high=&m=524271&mpage=1#524504

Nie wiem, age chyba kris w tym wątku o top pytał, może jest odpowiedź.

Zrobiłem poprawkę zgodnie z uwagami Tsuneo, dodałem extra cache z czymś w rodzaju read-ahead i zadziałało, uzyskałem ponad 2x większy transfer, który mnie satysfakcjonuje. Nie widzę dalej potrzeby aby w to wnikać. Moim celem była implementacja mass storage i już. Bez wnikania jak to działa, pod warunkiem, że spełnia moje oczekiwania. Darowanemu koniowi w zęby się nie zagląda :).

To jest w tym trybie, inaczej chyba msd nie działa.

Ale co ty z tym SD cały czas, tu chodzi o usb. Obsługa SD (w trybie spi) jest tak banalna, że nawet sobie wyrażam ją zrobioną w asm, żaden cymes. Aczkolwiek nie sądzę że z powodu jej prostoty w ams będzie szybsza/mniejsza (co kto woli) niż w C.

Na brak RAMu jeszcze nie narzekam: tcpip + ethernet + httpd (obsługa

10 połączeń na raz) + telnetd z microshell + obsługa usb pendrive (doc root) z 4k cache + obsługa 1wire + obsługa rfm12b zajmuje 24 kB RAM (w tym jest 2k stosu i 1k sterty na malloc). Flasha zajmuje 127kB z 128kB w pic32mx250. Wiadomo, że raki mcu to jest taka popierdułka, jest pewnym kompromisem między wydajnoscią a zużyciem energii. Jakbym chciał szybki usb czy ethernet to postawilbym jakieś raspbbery pi i w ogóle pisaniem softu bym sobie głowy nie zwracał tylko użył gotowce.

wypuszczaniu

procesorach

I co z tego że gigabajty? Rozwiązanie ma się dobrze sprzedać, nie ważne ile gigabajtów ma przerzucać. Jeśli będzie popyt na 12 rdzeniowe smartfony z dwu gigabajtowymi ikonkami to będzie to produkowane i producent nie będzie się naprężał, żeby ikonki były jedyno gigabajtowe.

Join the Discussion

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

Didn't find your answer?

Ask the community — no account required