CMSIS — część 3 – Przykłady –

CMSIS — część 3 – Przykłady –
Razem głosów: 16 co stanowi: 96.25% całości.

imgres

Wiecie tak sobie siedzę i rozmyślam nad sensem kontynuacji i w sumie wcale mi się nie chce pisać o CMSIS , ale przydałoby się oprzeć cały wywód o jakieś użyteczne przykłady by pokazać istotę ustroju na żywym organizmie, a nie na takich tam sobie teoretycznych rozważaniach, które w w sumie są dość nudne i dlatego teraz opiszemy co nieco….

Od razu bez owijania w bawełnę i folie bumbelkową :) przystępujemy do działania  :)       W celu wyjaśnienia stosowania CMSIS w rzeczywistych projektach, przyglądniemy się projektowi w sumie banalnemu.  Aplikacja pod rdzeń Cortex-M3. Program będzie kompilowany dla procesora STM32 z użyciem plików dostarczonych z uVision Keil-a. Zapewniam was ze niema to znaczenia bowiem przenoszenie na np IAR EWARM czy inny Jest banalnie proste. Wiele z definicji funkcji CMSIS   znajdziecie w  core.cm3.h jako funkcje statyczne inline. W zależności od poziomu optymalizacji kompilator odwołuje się do sekwencji instrukcji zamiast stosować rzeczywiste wywołania funkcji, przy czym jednocześnie zapewnia określony poziom bezpieczeństwa kodu.

W przykładzie użyjemy inicjalizacji zegara i GPIO. Timer dla SysTick ustawimy na 0,5s. Każde wywołanie obsługi przerwania zmieni stan GPIOB(15).


Przykład 1:

Dobrze nasz program którego działanie opiszemy wyżej zrealizujemy na początek za pomocą biblioteki FWlib dostarczanej przez STMicroelectronic, zapewnia ona nam prosty dostęp do wnętrzności  rdzenia Cortex-M3 oraz urządzeń peryferyjnych zawartych w naszym STM32.  Biblioteka FWlib  w sumie jest w większości oparta o CMSIS i można powiedzieć że części jej tworzą DPAL :)

A teraz ma?a obsługa przerwania, którą umieszczamy w pliku stm32f10x_it.c,  który zawiera szablony obsługi przerwań  popełnione przez ST w FWlib. Jako że są one puste (bez ciała) musimy dostosować je do realizacji naszego konkretnego zadania :)

I tak by to wyglądało w praktyce , jak widać nie jest tak strasznie prawda ?


 

Przykład 2:

Tak … No ładnie nam wyszło poprzednio miganie ale spróbujmy jednak przekształcić nasz program na prawdziwe CMSIS. JA używam V1P10, co może być istotne …. ale też niekoniecznie. Niemniej warto sprawdzić wersję :

Wstępne wsparcie dla mikrokontrolerów STM32 jest niejako częścią CMSIS i jest niejako osadzone w pliku nagłówkowym stm32.h.  W naszym przypadku stm32f10x.lib.h  poza stm32.h zasypie nas błędami ..spowodowane to jest wieloma definicjami funkcji i makr. By tego uniknąć będziemy musieli podejść selektywnie do nagłówków  FWlib.  Oczywiście wszystkie nagłówki FWlib zależą od definicji zawartych w plikach Cortex-M3 jak  core.h i  stm32f10x  plik map.h. Większość zawartych w tych 2ch plikach nagłówkowych definicji zostało już określone przez CMSIS i zdefiniowane w plikach core_cm3.h oraz system_stm32.h przez co będziemy udawać że oba pliki nagłówkowe FWlib zostały już w kodzie uwzględnione:)

Aktualna inicjalizacja systemu zostanie zamknięta niejako przez funkcję CMSIS  SystemInit(), która jest realizowana przez producenta krzemu (w naszym wypadku STM). Niejako jest to minimalny wymóg by tą funkcją zainicjować zegar systemowy naszego procesora. Gdy użyjemy stm32.c  w SystemInit() zainicjowane zostaną również interfejsy pamięci Flash. Ponadto CMSIS definiuje nam jedną zmienną systemową SystemFrequency, która odzwierciedla zarówno częstotliwość rdzenia jak i SysTick w Hz.  To minimum można powiedzieć absolutne choć w rzeczywistości  jak widać w pliku stm32.c pozwala jednak ładnie nam zademonstrować moc CMSIS mimo iż kilka zmiennych mamy już zdefiniowanych niejako dodatkowo do przechowywania wartości częstotliwości różnych zegarów dla różnych peryferii w mikrokontrolerach STM32.  Rdzeń i SysTick()  mogą pracować na różnych częstotliwościach (asynchronicznie) i należy zachować ostrożność podczas korzystania z częstotliwości systemu w programie :)

CMSIS nie inicjuje zegarów peryferyjnych urzędzeń dlatego pamiętać musimy by zastosować odpowiednią funkcję do włączenia zegara dla GPIO.

Z kolei konfiguracja grupy i priorytetów NVIC jest obsługiwana przez funkcję NVIC_SetPriorityGrouping() gdzie stosowane jest bezpośrednie kodowanie pola  PRIGROUP w SCB->AIRCR. Wybieramy wartość 4 co reprezentuje 3 bity dla grupy tzw (preempting) oraz 5 bitów dla sub priorytetów.  Ogólny wzór do obliczania właściwej wartości wygląda tak:

PROGROUP = bits sub-1

W odróżnieniu od pierwszej wersji wariant CMSIS jak widać ustawia najpierw priorytety. Poniekąd jest to część ustawienia inicjalizacji SysTick, ale to się wyjaśni za chwilę :)

Nic nie stoi na przeszkodzie by konfiguracji GPIO na porcie B dokonać przez zwykłe funkcje z FWlib :)

SysTick_Config(),który znajdziemy zaimplementowany w CMSIS w zasadzie jest rejestrem programowym z przeładowaniem wartości :) Ponadto funkcja wybiera też HCLK jako źródło zegara dla rdzenia , tym samym umożliwia ustawienie przerwań timera SysTick.  Funkcja ta tez ustala priorytet dla handlera SysTick na najniższy w systemie , co jest zalecane  gdy chcemy np korzystać z SysTick w systemie RTOS. W naszym przykładzie jednak „zażądamy” innego priorytetu i bezczelnie zastąpimy zakodowane wartości dodatkowym wywołaniem funkcji NVIC_SetPriority():)  Dzięki czemu będziemy abstrahować od różnic między obsługa systemu Cortex-M3, a zewnętrznymi przerwaniami. Przez co wszystkie konfigurowalne wyjątki systemowe zostaną określone przez zanegowane numery IRQ o czym pisałem wcześniej.

Kod obsługi przerwania SysTick nie wymaga żadnej modyfikacji. Nazewnictwo stosowane w FElib jest zgodne z CMSIS, a nazwy wszystkich wewnętrznych procedur obsługi wyjątków muszą się kończyć prefixem  _Handler. Natomiast nazwy obsługi przerwań zewnętrznych muszą się kończyć IRQ Handler. Dzięki czemu uzyskujemy dostęp do portów GPIO za pośrednictwem definicji funkcji  jak w FWlib.

I to na tyle jeśli chodzi o CMSIS , według mnie warto zgłębić temat gdyż jest warto i standard jaki wyrósł wnosi wiele pozytywnych cech i ułatwień podczas tworzenia naszych aplikacji na mikrokontrolery z rdzeniem ARM Cortex-M.

 

 

Podziel się na:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay