Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

STM32F4 USB HOST, HAL, FatFS - na co zwrócić uwagę?

arcyimperator 26 Dec 2019 14:19 555 3
  • #1
    arcyimperator
    Level 14  
    Cześć,
    ostatnio napisałem bootloader na STM32F4 pracujący w trybie USB HOST FS. Całość chodzi na Distortosie, używa HAL i bibliotek wygenerowanych przec CubeMX i zmodyfikowanych lekko przeze mnie. Modyfikację polegają głownie na:
    -modyfikacji obsługi przerwania:
    Code: c
    Log in, to see the code


    -właściwy kod obsługi przerwania wykonywany jest w zmodyfikowanym USBH_Process_OS ():
    Code: c
    Log in, to see the code

    HAL_HCD_IRQHandler nie jest już w kontekście przerwania.
    Przy okazji:priorytet wątku hosta musi być wyższy/równy niż wątków które dokonują odczytów/zapisów USB -one używają w pewnych miejscach pollingu i mogą zablokować system, taka uwaga.

    -modyfikacja USBH_UserProcess i dodanie API do odczytu stanu hosta:
    Code: c
    Log in, to see the code

    Aplikacja główna sprawdza czy podłączone urządzenie jest gotowe.

    -taka toporna implementacja kolejki zdarzeń, co prawda kod od ST wydaje się nie być zainteresowany tym co się stało i bazuje jedynie na aktualnym stanie:)
    Code: c
    Log in, to see the code


    Moje prośby i pytania:
    1. proszę o krótkie review czy kod który wrzuciłem ma jakieś zasadnicze wady, w szczególności czy obsługa przerwania (w wątku) jest prawidłowa?
    2. Jaką przyjąć strategię w kontekście montowania i odmontowania systemu plików? Moja propozycja jest taka: globalna flaga bool is_mounted; (z mutexem pewnie), montowanie gdy (USBH_STATE == USBH_READY&& is_mounted == false), odmontowanie za każdym razem gdy jest jakikolwiek błąd FatFS i is_mounted == true;
    3. Czy podwójne odmontowanie jest błędem?
    4. Zaintrygowany postem: https://www.elektroda.pl/rtvforum/viewtopic.php?p=18342564#18342564
    Czy HAL dla STM32F4 USB Host posiada jakieś znane błędy?

    Dziękuję za pomoc i pozdrawiam
  • #2
    Freddie Chopin
    MCUs specialist
    arcyimperator wrote:
    proszę o krótkie review

    Widzę że znalazłeś linki do tej dyskusji, ale warto wspomnieć i tu - https://github.com/DISTORTEC/STM32F7-USB-host-ME906-lwIP-MQTT - jest tu użyty host na F7, który jest zapewne identyczny jak na F4, więc większość rozwiązań można zastosować wprost. Zwracam Twoją szczególną uwagę na to, że w HALu i kodzie hosta musiałem wprowdzić pewne KRYTYCZNE poprawki, bez których ten cały kod nadawał się tylko do zabawkowych aplikacji demo udostępnianych przez ST. Myślę że w kodzie hosta i w HALu dla F4 są dokładnie te same błędy co w kodzie dla F7.

    Patrząc na szybko na Twój kod, na pewno blokowanie mutexa przed zrobieniem kopii zmiennej usbh_state jest zbędne - operacja kopiowania jest atomowa i tak. Z ciekawszych opcji mogę też polecić używanie np. `std::lock_guard` zamiast ręcznego bawiania się mutexem:

    
    #include <mutex>
    ...
    {
      const std::lock_guard<distortos::Mutex> lockGuard {usbh_mutex};
      ...
    }


    Być może również o tym wspominałem, ale w najnowszym masterze distortos jest też wsparcie dla systemu plików FAT, ale akurat nie przy użyciu FatFS - ta biblioteka to absolutne zaprzeczenie obiektowości... );
  • #3
    arcyimperator
    Level 14  
    Cześć,
    Quote:

    Widzę że znalazłeś linki do tej dyskusji, ale warto wspomnieć i tu - https://github.com/DISTORTEC/STM32F7-USB-host-ME906-lwIP-MQTT - jest tu użyty host na F7, który jest zapewne identyczny jak na F4, więc większość rozwiązań można zastosować wprost. Zwracam Twoją szczególną uwagę na to, że w HALu i kodzie hosta musiałem wprowdzić pewne KRYTYCZNE poprawki, bez których ten cały kod nadawał się tylko do zabawkowych aplikacji demo udostępnianych przez ST. Myślę że w kodzie hosta i w HALu dla F4 są dokładnie te same błędy co w kodzie dla F7.


    Porównałem te wylistowane commity z moim wygenerowanym kodem i jest już nieco inny:
    Link
    wygląda na połownicznie naprawiony (tylko w USB_HC_Halt):
    Code: c
    Log in, to see the code

    USB_StopHost:
    Code: c
    Log in, to see the code


    Link
    Dalej istnieje, przynajmniej punkt 1, co do hazardów nie jest w stanie się wypowiedzieć

    Link
    i
    Link
    też nie ma fixu

    Zauważyłem że Twoja implementacja obsługi przerwania to "domyślne"
    Code: c
    Log in, to see the code

    Co sądzisz mojej implementacji która jest powyżej (wszystko w wątku)? Wydaje mi się że rozwiązuje problemy związane z hazardami.
    Ponadto, czy HAL_HCD_IRQHandler nie wykonuje się czasami "długo" i blokuje procka?

    Dodaje jeszcze jedno pytanie: czy masz jakąś procedurę "ratunkową" gdy np. w losowym momencie coś pójdzie nie tak (np. usunięcie urządzenia w pośrodku operacji)? Ja mam na myśli coś takiego:
    1. zablokowanie przerwań
    2. (specyficzne dla klasy lub aplikacji czyszczenie, np. odmontowanie FSa)
    3. zresetowanie peryferium USB OTG FS
    4. DeInitStateMachine
    5. Init
    6. włączenie przerwań
    Domyślnie wygenerowany kod posiadał jakiś (pusty) USB_error_handler. Zastanawiam się czy potrzebny.

    Quote:
    Być może również o tym wspominałem, ale w najnowszym masterze distortos jest też wsparcie dla systemu plików FAT, ale akurat nie przy użyciu FatFS - ta biblioteka to absolutne zaprzeczenie obiektowości... );

    Prawdopodobnie się przesiądę bo FatFs czasami mnie wkurza:)



    Diękuję za odpowiedź i pozdrawiam!
  • #4
    arcyimperator
    Level 14  
    Cześć,
    w moim kodzie dodałem te poprawki
    https://github.com/DISTORTEC/STM32F7xx_HAL_Dr...mmit/688052cb223e737d08b63c7a3f3853d8ab1f9101
    i po intensywnych testach polegających na intensywnym wkładaniu i wyjmowaniu (:]) pendrive w losowych momentach, znalazłem jeszcze jedne problem, mianowicie funkcja USBH_HandleEnum() z usbh_core.c ignoruje błędy z USBH_Get_DevDesc(...) co w moim przypadku skutkuje zawieszeniem procesu do czasu następnej detekcji urządzenia. Rozwiązaniem jest myślę przejście do stanu disconnected, ale fix przetestuje dopiero jutro. Nie wiem nawet czy ten problem nie jest specyficzny tylko dla mojej implementacji.
    Co do procedury ratunkowej o której wspominałem, to wydaje mi się że przejście do stanu disconnected jest wystarczające dla ustabilizowania systemu hosta.
    Poza tą (rzadką) sytuacją o której wspomniałem działa toto stabilnie.

    Pozdrawiam