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

STM32 użycie biblioteki HAL lub LL bez CubeMX

andrzej_nied 14 Apr 2019 16:41 1665 4
  • #1
    andrzej_nied
    Level 13  
    Witajcie,
    od dłuższego czasu przymierzam się do przejścia na bibliotekę HAL lub LL dla STM32. Od wielu lat używam swoich własnych bibliotek (napisanych bezpośrednio na rejestrach) lub biblioteki STD. Jednakże przed użyciem HALa powstrzymuje mnie konieczność użycia CubeMX. Niby wszystko ok, ale nie do końca. Nie podoba mi się układ kodu generowanego przez ten system, a przede wszystkim konieczność pisania w zdefiniowanych miejscach pliku. Zastanawiam się czy istnieje możliwość aby użyć samej biblioteki HAL lub LL (to by było najlepsze) bez CubeMX? Używam Keila w najnowszej wersji. Niektóre systemy, potrafią same generować kod HAL, ale nie znalazłem takiego czegoś w Keilu.

    Pozdrawiam
    Andrzej
  • Helpful post
    #2
    ZbeeGin
    Level 39  
    Nie ma najmniejszego problemu by użyć bibliotek HAL lub LL bez konstruktora kodu CubeMX. Wystarczy je dodać do projektu, pokazać w przeszukiwanych ścieżkach i inkludować gdzie trzeba.

    Dodatkowo w symbolach dodać: "USE_HAL_DRIVER" dla HAL. W przypadku LL można dodać "USE_FULL_LL_DRIVER" by podstawowe konfiguracje przeprowadzać przez struktury, ale nie jest to konieczne, bo przecież można użyć niskopoziomowych makr.

    W przypadku HAL wypadałoby jeszcze nieco pogrzebać w pliku "stm32f0xx_hal_conf.h" by powyłączać nieużywane moduły, co znacznie skróci czas kompilacji. Oraz zwrócić szczególną uwagę na pliki, które w nazwie mają przyrostek "_template".

    Nie używam MDK więc dokładnej instrukcji ci niestety nie mogę podać. Możesz posłużyć się tym: https://stm32.eu/2015/12/13/pierwsze-kroki-z-...co-1-konfiguracja-srodowiska-mdk-armkeil-mdk/ eliminując punkty związane z samą płytką Discovery.
  • Helpful post
    #3
    rb401
    Level 38  
    andrzej_nied wrote:
    Nie podoba mi się układ kodu generowanego przez ten system, a przede wszystkim konieczność pisania w zdefiniowanych miejscach pliku.


    Nie musisz całkowicie rezygnować z CubeMX, bo jest dość pożyteczny.
    Ale możesz go użyć raz, jako "generatora" poprawnej aplikacji a później przerobić według uznania projekt, powyrzucać te specyficzne komentarze i inne rzeczy przerobić już po swojemu, a przy okazji przyjrzeć się filozofii HAL jak to jest zrobione przez CubeMX.
    Ale już później już nie odpalasz na tym projekcie CubeMX bo narobi Ci demolki.
    Za to można też mieć z boku drugi identyczny projekt, pusty, którego nie ruszasz, na którym tylko odpalasz CubeMX i na przykład dokładając peryferia czy modyfikując taktowanie, kopiujesz i wklejasz fragmenty kodu inicjacyjnego do swojego projektu, oszczędzając czas.

    Druga droga to wykorzystanie wzorcowych aplikacji lub szablonów z repozytorium CubeMX (swoją drogą bardzo wartościowe źródło informacji).
    Czyli w ustawieniach CubeMX wyszukujesz folder gdzie te repozytorium jest, szukasz tam gałęzi na uC, który masz i kopiujesz z tego repozytorium co najmniej folder projektu Templates czyli pustej aplikacji jaką potrzebujesz (ale bez naleciałości związanej ze specyfiką CubeMX ) lub coś z Examples.

    Tyle że musisz też do miejsca gdzie masz swoje projekty skopiować też koniecznie folder Drivers (bo tam jest HAL,LL,CMSIS itp.) i ewentualnie Middlewares (biblioteki typu FatFs, drivery do USB itd.). Bo wszystkie programy z repozytorium są ustawione na korzystanie z jednego egzemplarza bibliotek. Ale to już można zmienić według uznania.
    Później musisz w tych aplikacjach zmienić tylko ustawione tam ścieżki do bibliotek (w Drivers i Middlewares) na wynikające z tego jak sobie tam zorganizujesz w workspace.
    Albo od biedy, wręcz skopiować z repozytorium całą oryginalną strukturę folderu zawierającego foldery Drivers, Middleware i te z przykładami, ale to może być później trochę niewygodne.
    Każdy z przykładów i szablonów jest uniwersalny pod różne kompilatory, również pod Keila.
    Zresztą jak zajrzysz do tego repozytorium to będziesz widział o co chodzi. Są również opisy w każdym folderze projektów.
  • #4
    andrzej_nied
    Level 13  
    Dziękuję za informację. Faktycznie najlepszym wyjściem będzie użycie template wraz z zależnymi katalogami tak by tworzyły jednolity i przenaszalny projekt.

    W przypadku HALa nurtuje mnie jeszcze jedna rzecz. Jak wygląda sprawa z przerwaniami? Tam zamiast przerwań są używane callbacki. Czy to przypadkiem nie wydłuża czasu reakcji na przerwanie? Czy HAL daje możliwość klasycznej obsługi przerwań?
  • Helpful post
    #5
    rb401
    Level 38  
    andrzej_nied wrote:
    Jak wygląda sprawa z przerwaniami? Tam zamiast przerwań są używane callbacki.


    To nie tak jest. Callbacki są całkiem do czego innego.

    W programie HALowym, to użytkownik pisze obsługę przerwań sprzętowych (tak jak w klasycznym podejściu "rejestrowym") a specyfiką HAL jest tylko to że dostarcza pewnych gotowców na obsługę przerwań.

    Przykładowo weźmy uart. Jeśli chcemy używać wysokopoziomowych funkcji z użyciem przerwań np. HAL_UART_Transmit_IT to musimy najpierw napisać obsługę przerwania np. od UART1 i w niej wywołać ten HALowy gotowiec, w tym przypadku HAL_UART_IRQHandler.
    Umownym miejscem na pisanie funkcji obsługi przerwań jest plik stm32f1xx_it.c.
    Akurat w tym Templates może tego nie widzisz bo ten plik jest pusty jak chodzi o przerwania od peryferii. Tak że lepiej jest spojrzeć na ten plik w jakimś example gdzie używane sa funkcje HAL korzystające z przerwań np. UART_TwoBoards_ComIT.

    Tam już widać o co chodzi:
    Code: c
    Log in, to see the code


    gdzie #define USARTx_IRQHandler USART1_IRQHandler

    Czyli jest to po prostu funkcja której adres znajduje się w tablicy wektorów przerwań wywoływana bezpośrednio przez procesor.
    Tu akurat wywołuje się w niej tylko tego gotowca z HAL, ale nic nie stoi na przeszkodzie dopisać swoje rzeczy.

    Tak że faktycznie różnicy w obsłudze przerwań względem klasycznego programu na rejestrach nie ma. I nie ma żadnego opóźnienia.
    Jedynie ta obsługa w HAL startuje później o czas wywołania (i wyznaczenia argumentu jakim jest handle danego uartu) ale wobec wygody ogólnej obsługi to raczej mało znaczące.

    A jeśli byś potrzebował całkowicie swoją obsługę jakiegoś przerwania to dopisujesz funkcję obsługi pod odpowiednią nazwą w pliku stm32f1xx_it.c. Potrzebne nazwy funkcji zależnie od peryferii bierzesz z pliku o nazwie np. startup_stm32f102xb.s w Drivers>CMSIS>Device... .