Mam wieloletnie doświadczenie z 8-bitowymi rdzeniami różnych producentów - mianowicie 8051, PIC i AVR - i teraz mam Cortex M0 do zrozumienia. W szczególności ten , ale mam nadzieję, że możemy być bardziej ogólni.
Okazuje się, że jest to trochę więcej, niż się spodziewałem, z wieloma dokumentami opisującymi różne części systemu na różnych poziomach szczegółowości i żaden naprawdę nie widziałem, aby połączyć to wszystko razem. W porównaniu z posiadaniem jednego arkusza danych, który wyjaśnia wszystko. Rozumiem, że przede wszystkim mam o wiele więcej rzeczy do udokumentowania, ale zmiana formatu rzuca mnie na pętlę.
Powyższa witryna zawiera jeden dokument, który stanowi dobry przegląd każdego podsystemu i urządzenia peryferyjnego w oderwaniu, oraz drugi, który szczegółowo opisuje każdy rejestr, i mam cały kod źródłowy dla ich zestawu SDK, w tym pliki nagłówkowe i kilka skomplikowanych przykładów, ale nadal widzę nic, co opisuje, jak to wszystko się łączy.
Czy istnieje zwięzłe omówienie architektury Cortex, która wyjaśnia funkcję rzeczy, których mniejsze kontrolery po prostu nie mają - na przykład wiele warstw magistrali od procesora do urządzeń peryferyjnych, każdy z własnym zegarem nadzorującym - i jak one wszystkie się łączą?
Odpowiedzi:
Pracowałem nad AVR oraz MCU opartymi na ARM Cortex-M3 / M4 / R4. Myślę, że mogę udzielić ogólnych porad. Zakłada się, że programujesz w C, a nie w asemblerze.
Procesor jest właściwie łatwą częścią. Podstawowe typy danych C będą mieć różne rozmiary, ale i tak używasz uint8 / 16 / 32_t, prawda? :-) A teraz wszystkie typy liczb całkowitych powinny być dość szybkie, a 32-bitowe (int) są najszybsze. Prawdopodobnie nie masz FPU, więc unikaj liczb zmiennoprzecinkowych i podwójnych.
Najpierw pracuj nad zrozumieniem architektury na poziomie systemu. Oznacza to operacje wejścia / wyjścia, taktowanie, pamięć, resetuje i przerywa. Musisz także przyzwyczaić się do koncepcji urządzeń peryferyjnych mapowanych w pamięci. W AVR można uniknąć myślenia o tym, ponieważ rejestry mają unikalne nazwy z zdefiniowanymi dla nich unikalnymi zmiennymi globalnymi. W bardziej złożonych systemach powszechne jest odwoływanie się do rejestrów za pomocą adresu bazowego i przesunięcia. Wszystko sprowadza się do arytmetyki wskaźnika. Jeśli nie lubisz wskaźników, zacznij naukę już teraz.
W przypadku operacji we / wy dowiedz się, jak obsługiwane jest multipleksowanie peryferyjne. Czy istnieje centralna kontrola multipleksera, aby wybrać, które piny są sygnałami peryferyjnymi, a które GPIO? Czy ustawiasz piny w tryb peryferyjny za pomocą rejestrów peryferyjnych? I oczywiście musisz wiedzieć, jak skonfigurować GPIO jako wejścia i wyjścia oraz włączyć tryb otwartego drenażu i podciągania / opuszczania. Przerwania zewnętrzne zwykle należą również do tej kategorii. GPIO są dość ogólne, więc twoje wrażenia powinny ci dobrze tutaj służyć.
Zegary sprowadzają się do kilku rzeczy. Zaczynasz od źródła zegara, zwykle kryształowego lub wewnętrznego oscylatora RC. Służy do tworzenia jednej lub więcej domen zegarowych na poziomie systemu. Chipy o wyższej prędkości będą korzystać z PLL, który można potraktować jako mnożnik częstotliwości. W różnych punktach będą także dzielniki zegara. Kluczowe rzeczy, które należy wziąć pod uwagę, to jaka powinna być częstotliwość taktowania procesora i jakie prędkości bitowe są potrzebne twoim peryferiom komunikacyjnym. Zwykle jest to dość elastyczne. Gdy będziesz bardziej zaawansowany, możesz dowiedzieć się o takich trybach, jak tryby niskiego poboru mocy, które zwykle oparte są na bramkowaniu z zegarem.
Pamięć oznacza flash i RAM. Jeśli masz wystarczającą ilość pamięci RAM, często szybciej jest utrzymywać swój program na wczesnym etapie rozwoju, więc nie musisz programować flashowania w kółko. Dużym problemem jest tutaj zarządzanie pamięcią. Twój dostawca powinien dostarczyć przykładowe skrypty linkera, ale może być konieczne przydzielenie większej ilości pamięci na kod, stałe, zmienne globalne lub stos, w zależności od charakteru programu. Bardziej zaawansowane tematy obejmują bezpieczeństwo kodu i programowanie flash w czasie wykonywania.
Resety są dość proste. Zwykle trzeba tylko uważać na licznik czasu watchdoga, który może być domyślnie włączony. Resety są ważniejsze podczas debugowania, gdy wielokrotnie uruchamiasz ten sam kod. Łatwo przeoczyć błąd z powodu problemów z sekwencjonowaniem.
Są dwie rzeczy, które musisz wiedzieć o przerwaniach - jak je włączać i wyłączać oraz jak konfigurować wektory przerwań. AVR-GCC robi to drugie z makrami ISR (), ale w innych architekturach może być konieczne ręczne wpisanie adresu funkcji do rejestru.
Peryferia mikrokontrolera są zwykle od siebie niezależne, więc możesz się ich uczyć pojedynczo. Może pomóc wybrać jedno urządzenie peryferyjne i użyć go do nauki części rzeczy na poziomie systemu. Peryferia komunikacyjne i PWM są dobre do taktowania i we / wy, a timery są dobre do przerwań.
Nie daj się zastraszyć poziomem złożoności. Te „podstawowe” mikrokontrolery nauczyły cię już wiele tego, co musisz wiedzieć. Daj mi znać, jeśli potrzebujesz wyjaśnienia.
źródło
int
/int_leastN_T
typy dla zmiennych stosu.int_fastN_t
typów, a nieint_leastN_t
typów.int16_t
często będzie tak samo szybki jakint32_t
dla wartości przechowywanych w pamięci, ale Standard wymaga, aby na platformach, któreint
mają 17 bitów lub więcej,int16_t x=32767; x+=2;
musiał ustawićx
na -32767, często wymagając instrukcji rozszerzenia znaku, nawet jeśli kod by nigdy nie korzystaj z zachowania owijania.x+=2
użyciem legalnego byłoby używanie instrukcji dla typów 16-bitowych, ponieważ kompilator może założyć, że wartość nie zostanie zawinięta, a zatem użycie jej nie zmieni obserwowalnego zachowania. Myślę jednak , że ARM nie ma 16-bitowej instrukcji ADD, która by to umożliwiła. (Mogę się mylić, moja wiedza na temat zestawu instrukcji ARM nie jest zbyt dobra.)Warto pamiętać, że ARM jest właścicielem własności intelektualnej mikroprocesora, ale tak naprawdę nie wytwarza części. Zamiast tego producenci udzielają licencji na różne wersje procesorów ARM i produkują własne unikalne części z indywidualnym zestawem funkcji i urządzeń peryferyjnych.
Biorąc to pod uwagę, jeśli jesteś nowy w architekturze, prawdopodobnie warto zacząć od dokumentacji ARM, która jest zasadniczo dokumentacją bazową dla wszystkich takich mikroprocesorów.
Na przykład Cortex-M0 jest opisany na stronie internetowej ARM .
Istnieje również lista książek związanych z ARM, które zaspokajają różnorodne potrzeby i zainteresowania.
Wreszcie istnieją karty danych konkretnego producenta. W przypadku M0 Cypress, NXP i STMicroelectronics to tylko trzej spośród wielu producentów prawdziwych części opartych na Cortex-M0.
(I nie, nie pracuję dla ARM i nigdy nie mam.)
źródło
Jedną dużą różnicą jest użycie bibliotek dostarczonych przez dostawcę. W przypadku PIC, Atmels itp. Podstawowe biblioteki (dla gpio, timerów, adc itp.) Nie były używane przez większość programistów. Z mojego doświadczenia wynika, że ludzie używają ich (co najwyżej) jako przewodników podczas pisania własnego kodu.
Jednak w przypadku ARM biblioteki są prawie zawsze używane. Istnieje standard „CMSIS”, do którego przestrzegania zaleca się producentom. Większość robi. Pomaga w przenoszeniu kodu (między różnymi ARM i między producentami) i daje „znormalizowaną” metodę strukturyzacji kodu. Ludzie przyzwyczajają się do widzenia i rozumienia funkcji biblioteki.
Pewnie są programiści, którzy uzyskują bezpośredni dostęp do rejestrów, ale są to wartości odstające :)
Aby odpowiedzieć na twoje pytanie, bardzo pomocne okazało się przeczytanie dokumentacji Biblioteki. ST ma dobrze opracowany kod z dużym plikiem pomocy utworzonym przez Doxygen. Możesz zobaczyć, jakie są wszystkie opcje dla każdego modułu sprzętowego.
Aby użyć GPIO jako przykładu, funkcja inicjalizacji obsługuje:
Przeglądając opcje, możesz zobaczyć, co jest możliwe. I oczywiście nauczysz się przekazywać te opcje do funkcji Init!
OK, teraz, kiedy to powiedziałem, widzę, że twój konkretny ARM nie ma bibliotek zgodnych z CMSIS. Zamiast tego mają swój własny zestaw SDK do pobrania. Zacznę przeglądać ich dokumenty SDK.
Jeśli nie jesteś żonaty z tym konkretnym produktem, mogę polecić znalezienie innego dostawcy z bibliotekami bardziej zgodnymi. W każdym razie zamierzasz wspiąć się na krzywą uczenia się, więc równie dobrze możesz uczynić swoją inwestycję bardziej przenośną ...
ARM są fajne! Nie oglądałem się za siebie.
źródło
Dobry czas na przeprowadzkę; 8 bitów umiera szybko; kiedy możesz kupić płytę za 5 USD z (na przykład) STM32F103, który jest raczej zdolnym 32-bitowym mikrokontrolerem ARM (nawet z USB!), nie ma wątpliwości, że czasy się zmieniły.
Masz już doskonałe odpowiedzi, ale przede wszystkim powiedziałbym „zapomnij o montażu” i prawie „zapomnij o dbałości o to, jak procesor działa na niskim poziomie” - pewnego dnia będzie narożna skrzynka, w której musisz się w nią zagłębić (konkretna optymalizacja lub debugowanie), ale rdzenie ARM wykonują kod C wyjątkowo dobrze (zgodnie z projektem) i rzadko się zapuszczasz w głąb wnętrzności.
Oznacza to, że poświęcisz pewną ilość czasu na walenie z problemami z kompilatorami (a zwłaszcza linkerami i plikami makefile) objaśnianie ci błędów, ale wszystkie one są do pokonania.
Wrażenia na temat działania ARM (tj. Książek procesora ARM) są gęste i niezbyt interesujące aż do dnia, w którym faktycznie trzeba zoptymalizować (i będziesz zaskoczony, jak rzadko to się dzieje, gdy masz 32-bitowe rejestry i twój PLL) d Zegar procesora jest w zakresie 100 MHz).
Zestaw instrukcji ARM „old skool” jest znacznie łatwiejszy do odczytania z demontażu niż znacznie nowszy „Thumb2” - taki jest w większości nowoczesnych ARM-ów na poziomie mikrokontrolera (Cortex) - ale znowu wewnętrzne instrukcje instrukcji w asemblerze głównie znikają w tle; jeśli masz odpowiedni zestaw narzędzi (szczególnie porządny debugger na poziomie źródła z punktami przerwania / pojedynczym krokiem itp.), po prostu nie przejmujesz się zbytnio tym, że jest to ARM.
Gdy znajdziesz się w świecie 32-bitowych rejestrów i 32-bitowych szerokości magistrali danych i wszystkiego, co kiedykolwiek chciałeś, dostępne na chipie, nigdy nie będziesz chciał wrócić do 8-bitowego procesora; w zasadzie często nie ma kary za „łatwe” i pisanie kodu, aby był bardziej czytelny niż wydajny.
Jednak ... urządzenia peryferyjne ... tak i jest tarcie.
Na pewno masz mnóstwo rzeczy do zabawy na nowoczesnych MCU, a wiele z nich to dość fantazyjne rzeczy; często znajdziesz świat wyrafinowania daleko poza AVR, PIC i 8051 urządzeniami peryferyjnymi.
Jeden programowalny zegar? Nie, miej osiem! DMA? Co powiesz na 12 kanałów z programowalnym priorytetem i trybem seryjnym oraz trybem łańcuchowym i automatycznym przeładowaniem oraz
I2C? I2S? Dziesiątki opcji miksowania pinów? Piętnaście różnych sposobów przeprogramowania pamięci flash na chipie? Pewnie!
Często wydaje się, że przeszedłeś z głodu na ucztę z urządzeniami peryferyjnymi i często zdarza się, że są całe fragmenty układu, które podziwiasz, ale których prawie nie używasz (stąd; zegar bramkowy).
Ilość sprzętu na chipie (i odmiany tego tylko w linii chipów jednego dostawcy) jest obecnie dość zadziwiająca. Jeden sprzedawca chipów będzie oczywiście ponownie używał bloków IP, więc kiedy poznasz pewną markę, staje się to łatwiejsze, ale „gówno zrobiło się teraz craaaazy”.
W każdym razie urządzenia peryferyjne i ich interakcje (i DMA i przerwania i alokacja magistrali oraz i i ...) są tak skomplikowane (i czasami nie dokładnie tak , jak opisano w arkuszach danych), że inżynierowie często mają ulubiony zakres jednostek MCU ARM i mają tendencję do trzymania się tego po prostu dlatego, że znają urządzenia peryferyjne i narzędzia programistyczne.
Dobre biblioteki i narzędzia programistyczne (tj. Szybka kompilacja + cykl debugowania z odpowiednim debuggerem) oraz duży zestaw przykładowych projektów kodu przykładowego są obecnie absolutnie kluczowe dla twojego wyboru ARM MCU. Wygląda na to, że większość dostawców ma teraz wyjątkowo tanie tablice ewaluacyjne (
Jak jestem pewien, zauważyłeś, że kiedy przekroczysz poziom mikrokontrolera z ARM i przejdziesz do poziomu SOC (np. SOC w stylu Raspberry Pi / itp.), Reguły zmieniają się całkowicie i wszystko zależy od tego, jaki rodzaj Linuxa wybierasz uciekać, ponieważ - z znikoma nielicznymi wyjątkami - wariowałbyś, próbując cokolwiek innego.
Gruntownie; bez względu na procesor, który (być może) został wcześniej wybrany dla ciebie na tym koncercie, kup sobie garść super tanich płyt ewaluacyjnych opartych na Cortex od kilku różnych dostawców (TI, STM, Freescale i więcej) zrób hack z dostarczonym przykładowym kodem.
Ostatnia rada; gdy znajdziesz stronę trzecią lub trzecią w arkuszu danych opisującym opcje miksowania pinów dla dokładnego numeru części, z którym pracujesz, możesz wydrukować go i przykleić na ścianie. Dowiedzenie się późno w projekcie, że pewna kombinacja urządzeń peryferyjnych jest niemożliwa z powodu multipleksowania pinów, nie jest przyjemnością, a czasami te informacje są tak zakopane, że przysięgam, że próbują to ukryć :-)
źródło
Pochodzę również z AVR i teraz zwykle trzymam się STM32 (Cortex-M). Oto, co polecam na początek, i odzwierciedla moje własne trudności, kiedy zaczynałem:
Zdobądź płytkę z debuggerem lub przynajmniej złącze JTAG (a następnie kup debugger JTAG). W okolicy jest wiele tanich i dzięki temu zaoszczędzisz dużo czasu.
Zdobądź dobre IDE ze wszystkim, co zawiera. Kiedyś polecić CooCox CoIDE dawno temu. Od tego czasu program został zatrzymany i wznowiony, więc nie jestem pewien, jak to jest teraz. „Dobre IDE” pozwala błyskawicznie migać diodą LED Hello World.
„Dobre IDE” powinno skonfigurować nagłówki CMSIS producenta. Zasadniczo są to mapy rejestrów, które umożliwiają łatwiejsze pisanie programów C / C ++, z nazwami zmiennych zamiast zwykłych liczb i wskaźników.
Spróbuj użyć bibliotek peryferyjnych producenta, jeśli nie potrzebujesz absolutnie najlepszej wydajności. Na razie tego nie robisz, ponieważ się uczysz. Jeśli później okaże się, że musisz wycisnąć więcej, zajrzyj do kodu biblioteki, aby zobaczyć, jak to robi. Dobrą rzeczą w bibliotekach jest to, że zwykle pozwalają one na użycie wielu różnych układów tego samego producenta z tym samym kodem.
W przeciwieństwie do AVR, układy ARM zaczynają się od wyłączonych urządzeń peryferyjnych. Musisz je najpierw włączyć. Dobra biblioteka urządzeń peryferyjnych zawiera przykłady prawidłowego korzystania z urządzeń peryferyjnych, a więcej informacji można uzyskać z arkusza danych urządzenia. Pamiętaj więc, aby włączyć zegary i urządzenia peryferyjne przed ich użyciem. Tak, nawet porty I / O są uważane za urządzenia peryferyjne.
Koduj, jak się uczysz. Nie próbuj omijać wszystkiego naraz, ponieważ naprawdę jest to dość skomplikowane. Zacznę od nauki drzewa zegara (autobusy APB, AHB itp.) Oraz interakcji między zegarami i dzielnikami zegara. Potem sprawdziłbym, gdzie IDE przechowuje skrypty linkera i kod startowy dla twojego urządzenia. Skrypt linkera jest podobny do sposobu organizacji pamięci (gdzie jest RAM, flash, tablica wektorów ISR itp.). Skrypt startowy konfiguruje program (takie jak kopiowanie inicjatorów zmiennych globalnych z pamięci flash do pamięci RAM). Niektóre IDE mają skrypty startowe w ASM, a niektóre w C. Czasami możesz wybrać Google dla innego, w wybranym przez siebie języku.
Uruchom debugger jak najszybciej. Na początku często popełnia się błąd, wykonując pewne czynności (zwykle inicjalizację sprzętową) w innej kolejności niż powinna. To czasami wyzwala wyjątek ISR, który powoduje, że jesteś w
while(1);
nieskończonej pętli (domyślna implementacja dla tego ISR), która zatrzymuje Twój program i jest trudny do wyśledzenia nawet za pomocą debuggera. Wyobraź sobie bez debuggera.Mówiąc o debuggerze, spróbuj uruchomić UART, a następnie użyj przejściówki USB do odczytu.
printf()
debugowanie jest zawsze przydatne :-)źródło
Nie pracowałem dużo na 8051, AVR lub PIC. Ale ostatnio zacząłem patrzeć na linię procesorów ARM Cortex MX. Dlatego nie mogę ci wiele powiedzieć o przejściu z 8051, AVR lub PIC, ale głównie z punktu widzenia początkującego.
Procesor ARM®Cortex ™ -M4 jest oparty na architekturze Harvard, a zatem ma osobne magistrale danych i instrukcji. Poniżej znajduje się obraz wysokiego poziomu.
W tym tygodniu przedstawiciele NXP będą odwiedzać nasz zakład. Sprawdzę u nich zasoby NXP ARM-Cortex Mx i opublikuję je tutaj. Freescale ma 32-bitowy mikrokontroler (MCU) Kinetis Low Power oparty na rdzeniach ARM® Cortex®-M. Rozumiem, że mają one również podobne przewodniki do nauki procesorów ARM. Niestety ich nie badałem.
Referencje:
źródło