Czy każda linia mikrokontrolera ma własny język programowania / składnię?

10

Zaprogramowałem Arduino i zacząłem programować Teensy. Są podobne do C, ale w języku programowania występują niewielkie niuanse.

Na przykład w C Arduino wywołujesz funkcję pinMode (pin #, Output / Input), aby wyznaczyć cyfrowy pin do wysyłania lub odbierania sygnałów. W Teensy's C ustawiasz rejestr „DDR” powiązany z jednym z czterech portów (z których każdy reprezentuje kolekcję pinów), które wspólnie określasz jako wejście lub wyjście ( składnia Teensy IO ).

Chciałbym wiedzieć, czy w przypadku korzystania z nowego mikrokontrolera trzeba skutecznie nauczyć się nowego „języka”. W cudzysłowie wstawiam słowo „język”, ponieważ pomimo niuansów w składni komponenty i sposób ich konfiguracji w oprogramowaniu są zasadniczo równoważne, np. Pojęcie portów i pinów nadal odnosi się do terminala, z którego można wyprowadzać / wprowadzać cyfrowe sygnały.

Z tej samej próżności dyskursu: czy istnieją mikrokontrolery, które nie są programowane w oprogramowaniu, czy też zawsze będzie istniała warstwa oprogramowania służąca do programowania sterownika uController? Jeśli ten ostatni, kto pisze / udostępnia dla nich dokumentację?

Minh Tran
źródło
2
Język programowania Arduino jest C ++ (nie (tylko) C) - a może po prostu podzbiorem C ++ (lub nawet tworzenie ). Nie jest do końca jasne, ale z pewnością jest więcej niż C; na przykład ma klasy i operator definiowany przez użytkownika + = .
Peter Mortensen,
1
Jest to C ++, kompiluje się przy użyciu g ++ - avr. Technicznie byłby to wolnostojąca implementacja C ++ i nie zawiera standardowej biblioteki C ++ (z uwagi na takie rzeczy, jak dynamiczna alokacja pamięci i wyjątki są konieczne). Możesz używać funkcji językowych, takich jak klasy i szablony, widziałem zastąpienie digitalWrite () oparte na szablonie, które osiąga taką samą wydajność jak bezpośredni dostęp do rejestrów, metoda Arduino ma dość narzutu.
r_ahlskog
1
Język jest taki sam. To interfejs API jest inny. Jeśli odejdziesz od mikrokontrolerów i zaczniesz pisać aplikacje komputerowe, napotkasz dokładnie te same problemy, gdy piszesz programy C dla systemów Windows, Linux i Mac. Nawet jeśli używasz wyłącznie POSIX API (który obsługuje wszystkie 3 platformy), nadal będziesz uderzał w różnice specyficzne dla platformy, gdy chcesz zapisać ustawienia / preferencje użytkownika.
slebetman

Odpowiedzi:

3

Mikroprocesory i mikrokontrolery zwykle wykorzystują wspólną architekturę między różnymi liniami produktów i producentów. Te architektury zwykle definiują zestaw poleceń niskiego poziomu ( zestaw instrukcji ) wspólny dla wszystkich implementacji. Kompilator AC lub C ++ będzie w stanie wygenerować kod bajtowy wykonywalny na wszystkich np. Procesorach ARM.

Jednak architektura to tylko połowa obrazu. Ponieważ istnieje wiele konkretnych adresów pamięci, wbudowane urządzenia peryferyjne, zarządzanie pamięcią i inne szczegóły implementacji, których architektura nie uwzględnia

Producent lub strona trzecia zazwyczaj dostarcza zbiór plików źródłowych ( HDK ), które zapewnią definicje, mapowania portów i przykładowy kod. Zazwyczaj HDK jest dla C i C ++ . Zazwyczaj HDK będzie mieć z nią powiązaną tablicę demonstracyjną (pomyśl 500 dolarów arduino). Często potrzebne są szczegółowe prace konfiguracyjne w celu dostosowania platformy programistycznej / przykładowej do projektowanego urządzenia

Arduino jest oparte na architekturze AVR i jest głównie obsługiwane przez Atmel. Arduino stworzyło bootloader platformy oraz bibliotekę uproszczonych funkcji i obiektów C ++, abyś mógł korzystać z platformy przy minimalnym wysiłku. Platforma Arduino i IDE jest przeznaczona dla hobbystów z minimalnym wyposażeniem. Przed arduino PIC pełnił podobną rolę w łatwym w użyciu i tanim środowisku BASIC.

W środowisku profesjonalnym zazwyczaj wsparcie to zapewnia sprzedawca / producent lub zleca je stronom trzecim. Zapewniają kod niskiego poziomu i nagłówki, a ty piszesz swoją aplikację za pomocą tego HDK, w większych organizacjach można to zrobić na miejscu. Niedawno producenci zaczęli budować otwarty ekosystem API / oprogramowania wokół swojej platformy, dzięki czemu są równie łatwe w użyciu od razu po wyjęciu z pudełka, jak arduino. Wciąż istnieje niezliczona ilość układów z niewielkim wsparciem programistycznym, a większość wiedzy na temat platform jest zamknięta w świecie korporacyjnym.

poważny
źródło
14

Język w tym przypadku jest dokładnie taki sam. Środowisko Arduino ma kilka dodatkowych bibliotek (tylko więcej kodu C), które „zawijają” dostęp do rzeczywistych rejestrów sprzętowych (DDRx, PORTx, INx itp.) Z nieco bardziej przyjaznymi dla użytkownika funkcjami. Zwiększa to narzut (więcej instrukcji należy wykonać dla tej samej operacji), ale zwiększa elastyczność, ponieważ „proste” jest napisanie programu, który korzysta tylko z tych wywołań, a następnie przekierowanie go na inny układ (np. Arduino mega) i biblioteka będzie obsługiwać prawidłowe mapowanie wewnętrznie.

Tak naprawdę nie ma żadnych „standardowych” interfejsów API dla naprawdę niskiego poziomu dostępu między chipami różnych dostawców. Jednak cały dostęp niskiego poziomu odbywa się w ten sam sposób - odczytuje i zapisuje na ustalone adresy pamięci - więc ogólna metoda dostępu będzie podobna dla różnych części, tylko szczegóły i nazwy będą różne. Być może dostarczysz pliki nagłówkowe z ogromnymi listami adresów rejestrów #defines przesyłanych do wskaźników. A może pliki nagłówkowe będą używać struktur do utrzymywania porządku przy odrobinie hierarchii. Niektórzy producenci mogą również oferować interfejsy API wyższego poziomu. Może to być bardzo przydatne w przypadku skomplikowanych i trudnych do skonfigurowania urządzeń peryferyjnych. GPIO jest bardzo proste, ale coś w rodzaju kontrolera USB z obsługą DMA może mieć setki rejestrów.

Więc sedno brzmi: tak, musisz nauczyć się nowych nazw rejestrów, ale językiem nadal jest C ++ (lub C, asembler, a może coś bardziej ezoterycznego).

alex.forencich
źródło
4
Arduino to nie tylko C (właściwie C ++) - ma preprocesor, który wprowadza kilka zmian przed podaniem go do kompilatora C.
Nick Johnson
W rzeczywistości dla Arduino jest to więcej niż C. Jest to C ++ (a może podzbiór C ++).
Peter Mortensen
Czy to tylko natywny C ++ z bibliotekami Arduino, czy coś więcej?
kayleeFrye_onDeck
Arduino IDE najwyraźniej ma trochę dodatkowego przetwarzania wstępnego w porównaniu do skądinąd standardowego C ++. Większość IDE tego nie robi.
alex.forencich,
Zasadniczo jest to C ++, ale z main()wstępnie zdefiniowanym dla Ciebie. Zamiast tego dostajesz dwa punkty wejściowe: init()i loop()(popraw mnie, jeśli się mylę, ale dotknąłem Arduino tylko na biegunie 20 stóp)
Slebetman
5

Mylisz mikrokontrolery i kompilatory. Języki wysokiego poziomu, w których można zaprogramować konkretną mikro, zależą od tego, jakie kompilatory są dostępne dla tej mikro.

Na niskim poziomie mikro wykonuje instrukcje maszynowe, które kompilator wyprowadza dla pliku tekstowego, który dajesz mu, który uważasz za „program”. Naprawdę określasz jakąś logikę do wykonania, a kompilator wymyśli, jak użyć dostępnych instrukcji maszynowych do implementacji tej logiki. W tym przypadku to, co programujesz, jest funkcją kompilatora, a nie rodzimym zestawem instrukcji mikro.

Możesz zaprogramować mikro, bezpośrednio podając instrukcje natywne. Odbywa się to za pomocą języka asemblera. Asembler, podobnie jak kompilator, jest tłumaczem, który pobiera zapisany plik tekstowy i w rezultacie tworzy instrukcje maszynowe. Różnica polega na tym, że w tym przypadku podajesz bezpośrednio instrukcje maszyny. Każda instrukcja ma nazwę i piszesz te nazwy zamiast binarnych kodów operacyjnych, ale nadal podajesz instrukcje bezpośrednio. Asembler wykonuje jedynie pomruk, polegający na ustaleniu dokładnego kodowania binarnego każdej instrukcji na podstawie nazwy i opcji zapisanych w pliku tekstowym.

Podczas gdy język wysokiego poziomu może być taki sam na bardzo różnych mikrach, instrukcje maszynowe są zwykle podobne tylko w rodzinie powiązanych mikr. Na przykład wszystkie Microchip PIC 18 mają ten sam zestaw instrukcji (głównie), który różni się od podstawowego PIC 16 i ponownie różni się od 16-bitowych części, takich jak PIC 24 i dsPIC 30 i 33.

Olin Lathrop
źródło
1
Asembler rozwiązuje również etykiety dla instrukcji skoku, co jest bardzo podatne na błędy, gdy wykonuje się je ręcznie.
Pete Becker,
2

Językiem programowania jest nadal C. Jednak biblioteka producenta, która ma dostęp do sprzętu, jest inna. O ile wiem, nie ma standardu, więc każdy producent ma swój własny interfejs API. Jeśli chcesz być przenośny między różnymi producentami, możesz chcieć wprowadzić swój własny abstrakcyjny interfejs API, aby uzyskać dostęp do sprzętu za pomocą określonych implementacji, które odwzorowują interfejs API na metody specyficzne dla producenta.

MrSmith42
źródło
W rzeczywistości jest to więcej niż C. To jest C ++ (a może podzbiór C ++).
Peter Mortensen
2

Inne odpowiedzi wprowadziły rozróżnienie między językami wysokiego poziomu (takimi jak C ++) a kodem maszynowym, chociaż nie sądzę, aby unieważniało to stwierdzenie, że każdy mikrokontroler ma powiązany „język”.

Różnice w implementacjach językowych nie są wystarczająco duże, aby można je było zaklasyfikować jako różne języki, choć nie zawahałbym się rozróżnić na „dialekty”. Mogą tu istnieć dwie warstwy zmian.

  1. Wysokopoziomowe biblioteki opakowań mogą być dostępne od producenta lub innej firmy
  2. Niektóre kompilatory mogą nie emitować kodu zgodnego ze standardami

Weźmy te punkty, obserwując platformę Arduino.

  • Społeczność Arduino udostępnia mocno abstrakcyjne biblioteki C ++ dla układów architektury AVR. Te biblioteki sugerują inny przepływ sterowania niż można by oczekiwać od typowego programu w C ++ (np. Ukrywanie main ()).
  • Pod maską Arduino kompiluje swój kod za pomocą avr-gcc, który emituje kod C / C ++. Wyjątki nie są jednak obsługiwane przez układy AVR i prawie zawsze są wyłączone. Przy braku tak dużej funkcji wynikowy program może nie działać tak, jak działałby „zwykły” program C ++.

Wiedząc o tym, jak zdecydujesz, jak zaprogramować dowolny dowolny mikrokontroler? Masz kilka opcji:

  1. Wyszukaj biblioteki i środowiska IDE dla określonego układu. Układy AVR są czasami opracowywane przy użyciu tylko C, ale projekt Arduino zapewnia bardziej przyjazne dla użytkowników hobby.
  2. Znajdź kompilatory, które są w stanie skompilować dla twojego konkretnego układu. Dzięki właściwemu kompilatorowi, arkuszom danych twojego układu i pewnej cierpliwości będziesz mógł pisać kod bardzo blisko metalu.

Dla odniesienia, oto lista obsługiwanych backendów dla GCC. Zauważysz, że istnieje wsparcie dla ARM, AVR, MIPS i kilku innych.

Informacje o układach, które nie są zaprogramowane za pomocą „oprogramowania” ...

Możesz zajrzeć do programowalnych tablic bramek (FPGA)! Układy FPGA są kontrolowane przez zmianę wartości tabel przeglądowych w celu emulacji bramek logicznych. Nie ma ono odpowiedniej formy oprogramowania, ale nadal jest rozwijane przy użyciu języków opisu sprzętu, takich jak VHDL i Verilog.

Strangework
źródło
1

Patrzę na jedną płytkę drukowaną i widzę niektóre urządzenia do montażu powierzchniowego, niektóre oporniki, kondensatory i diody LED. Czy to oznacza, że ​​ponieważ jedna z tych kart jest kartą wideo, wszystkie karty z rezystorami i kondensatorami oraz wieloma warstwami i śladami są kartami wideo? Nie.

Oto kolejny przykład, ta strona używa alfabetu angielskiego i angielskich słów. Czy więc strona z nowymi czasami w jorku, czy to czyni tę stronę z nowymi czasami w jorku? Nie, po prostu dzielą ten sam alfabet i język, ale poza tym są zupełnie inne.

C jest językiem programowania ogólnego przeznaczenia, który wyodrębnia zestaw instrukcji poniżej. Może być używany do samego metalu, może być używany do tworzenia różnych i niekompatybilnych ze sobą systemów operacyjnych, może być używany do tworzenia gier wideo itp. Wszystkie z nich używają tego samego podstawowego języka C, niektórych typowych funkcji i konstrukcji C, a także utworzone przez nich wywołania funkcji specyficzne dla aplikacji docelowej. Dla każdej wspomnianej platformy lub innych może istnieć zestaw funkcji, które ktoś postanowił utworzyć. Podobnie jak do tej pory garstka ludzi, w tym ja, dała ci tę samą odpowiedź, ale napisała ją w inny sposób. Weź 100 programistów i odizoluj ich od siebie i powierz im zadanie programowania w celu rozwiązania określonego problemu, nie ograniczając całkowicie swobody programowania, a otrzymasz od 1 do 100 różnych, niekompatybilnych ze sobą rozwiązań, prawdopodobnie nie 1, ale kilka wspólnych tematów w zależności od ich szkolenia i doświadczenia, a następnie nazwy zmiennych i nazwy funkcji, które jako zestaw są prawdopodobnie unikalne dla każdej osoby. Weź te same tablice, o których już mówisz, a przekonasz się, że z pewnością mam własny kod C, który jest niekompatybilny (z funkcjami arduino), aby działać na nich, podobnie jak wiele innych, a także niekompatybilny z innymi platformami. Na tym polega piękno programowania osadzonego na gołym metalu, nie jesteś w żaden sposób ograniczony, nie musisz mieszkać w standardowych wywołaniach bibliotek systemu operacyjnego lub ograniczonym gui zbiorem reguł itp. Pełna swoboda. prawdopodobnie nie 1, ale kilka popularnych tematów w zależności od ich szkolenia i doświadczenia, a następnie nazwy zmiennych i nazwy funkcji, które jako zestaw są prawdopodobnie unikalne dla każdej osoby. Weź te same tablice, o których już mówisz, a przekonasz się, że z pewnością mam własny kod C, który jest niekompatybilny (z funkcjami arduino), aby działać na nich, podobnie jak wiele innych, a także niekompatybilny z innymi platformami. Na tym polega piękno programowania osadzonego na gołym metalu, nie jesteś w żaden sposób ograniczony, nie musisz mieszkać w standardowych wywołaniach bibliotek systemu operacyjnego lub ograniczonym gui zbiorem reguł itp. Pełna swoboda. prawdopodobnie nie 1, ale kilka popularnych tematów w zależności od ich szkolenia i doświadczenia, a następnie nazwy zmiennych i nazwy funkcji, które jako zestaw są prawdopodobnie unikalne dla każdej osoby. Weź te same tablice, o których już mówisz, a przekonasz się, że z pewnością mam własny kod C, który jest niekompatybilny (z funkcjami arduino), aby działać na nich, podobnie jak wiele innych, a także niekompatybilny z innymi platformami. Na tym polega piękno programowania osadzonego na gołym metalu, nie jesteś w żaden sposób ograniczony, nie musisz mieszkać w standardowych wywołaniach bibliotek systemu operacyjnego lub ograniczonym gui zbiorem reguł itp. Pełna swoboda. Weź te same tablice, o których już mówisz, a przekonasz się, że z pewnością mam własny kod C, który jest niekompatybilny (z funkcjami arduino), aby działać na nich, podobnie jak wiele innych, a także niekompatybilny z innymi platformami. Na tym polega piękno programowania osadzonego na gołym metalu, nie jesteś w żaden sposób ograniczony, nie musisz mieszkać w standardowych wywołaniach bibliotek systemu operacyjnego lub ograniczonym gui zbiorem reguł itp. Pełna swoboda. Weź te same tablice, o których już mówisz, a przekonasz się, że z pewnością mam własny kod C, który jest niekompatybilny (z funkcjami arduino), aby działać na nich, podobnie jak wiele innych, a także niekompatybilny z innymi platformami. Na tym polega piękno programowania osadzonego na gołym metalu, nie jesteś w żaden sposób ograniczony, nie musisz mieszkać w standardowych wywołaniach bibliotek systemu operacyjnego lub ograniczonym gui zbiorem reguł itp. Pełna swoboda.

Możesz wybrać, a wysoki odsetek ludzi, grać w czyimś piaskownicy zamiast budować własny, co oznacza użycie arduino gui i ich bibliotek C.

Możesz wziąć ten sam komputer i uruchamiać różne wersje systemu Windows it, Linux, BSD i listę prania innych systemów operacyjnych, które na pewnym poziomie używają C, ale których wywołania funkcji są ze sobą niezgodne. Ten sam sprzęt i niekompatybilny C, który obejmuje inny sprzęt, ten sam język, może mieć zgodny lub niekompatybilny kod. Język w żaden sposób nie czyni ich kompatybilnymi.

C jest używany na tych wbudowanych platformach, ponieważ jest to powszechna praktyka, nie ma innego języka, który mógłby zastąpić C. Pierwszym krokiem dla nowego procesora jest oczywiście montaż, a następnie prawie zawsze jest C, a potem inne, jeśli jest wystarczająco wydajny, aby uruchomić system operacyjny (linux, bsd itp.). C został wynaleziony i miał nadzieję rozwiązać problem związany z portowaniem kodu między platformami, i tak długo, jak masz system operacyjny, taki jak kompilator kompatybilny z C, tworzący kod, który DZIAŁA NA SYSTEMIE OPERACYJNYM, zrobi standardowy plik C operacje i printf i takie rzeczy. Ale goły metal to inna historia, nie ma systemu operacyjnego, często nie ma pojęcia o systemie plików ani o wyświetlaniu, ale powszechną praktyką jest prawdopodobnie kompilator C, który u podstaw przekształca C w język docelowy asemblera.

old_timer
źródło
W rzeczywistości dla Arduino jest to więcej niż C. Jest to C ++ (a może podzbiór C ++).
Peter Mortensen
1

Aby odpowiedzieć na drugie pytanie, termin „mikrokontroler” oznacza, że ​​układ ma procesor i pamięć RAM (i prawdopodobnie ROM) na pokładzie. Wszystkie mikrokontrolery uruchamiają oprogramowanie - dlatego je lubimy.

Przechodząc głębiej do pierwszego pytania, zauważ, że chociaż (prawie?) Wszystkie MCU mają kompilator C, podstawowy język C nie obsługuje każdej instrukcji na każdym procesorze. Na przykład C ma przesunięte lewe / prawe operatory, ale nie ma obrotowych lewych / prawych operatorów. System wskaźników C nie obsługuje naturalnie oddzielnych przestrzeni programów i danych (jak w niektórych architekturach Harvarda). C nie ma bezpośredniego wsparcia SIMD.

Kompilatory mają kilka opcji radzenia sobie z tymi funkcjami:

  1. Rozszerz podstawowy język, zwykle o nowe słowa kluczowe (np. Bliskie i dalekie dla stronicowanych wspomnień).

  2. Zapewnij funkcje wewnętrzne (np. __Ror () i __rol () do obrotu).

  3. Przeprowadź je w optymalizatorze, aby sekwencje operacji C zostały skompilowane w jedną wydajną instrukcję (np. Mnożenie / kumulowanie).

  4. Zignoruj ​​je i zmuś użytkownika do napisania kodu asemblera, jeśli chce funkcji niestandardowych.

Następny poziom to dostarczone przez producenta pliki nagłówkowe, które głównie definiują dla ciebie wszystkie rejestry. Możesz sam to zrobić, ale to duży ból, chyba że jesteś ekspertem w tej MCU.

Wreszcie istnieją funkcje biblioteczne dostarczone przez producenta, które obsługują takie proste czynności, jak zapisy rejestru dla Ciebie.

Twój przykład łączy dwa poziomy. DDR to makro odnoszące się do rejestru. Jest zaimplementowany jako dostęp do wskaźnika lub wewnętrzna funkcja kompilatora (nie pamiętam która). pinMode () to funkcja, która zapisuje dla ciebie rejestr DDR.

Przechodząc z jednej linii MCU do drugiej, musisz nauczyć się nowych rejestrów i nowych dziwactw kompilatora. Jeśli pozostaniesz w tej samej firmie, możesz uzyskać podobny interfejs API. Różne firmy nie udostępniają interfejsów API; dlaczego pomożemy Ci przejść do naszych konkurentów? :-)

Adam Haun
źródło
1

Mikrokontrolery często mają różne mikrokody na poziomie sprzętowym. Aby uchronić nas przed wprowadzaniem kodu maszynowego (tj. Instrukcji w postaci liczb - każdy reprezentujący surowy mikrokod mikrokontrolera) lub w asemblerze symbolicznym (który zapewnia etykietę mnemoniczną dla każdej instrukcji kodu maszynowego), używane są przenośne języki wysokiego poziomu.

C i Forth zostały zaprojektowane z myślą o łatwości przenoszenia w różnych zestawach kodów maszynowych.

Więc jeśli używasz C na Arduino i C na Teensy, używasz C w obu przypadkach.

Jeśli użyjesz Fortha na Arduino i Fortha na Teensy, użyjesz Fortha w obu przypadkach.

Czasami dodatkowe urządzenia sprzętowe podpowiadają osobie (lub grupie) przenoszącej język na nowy sprzęt, aby napisał wstępnie przygotowany kod, aby umożliwić dostęp do nowych udogodnień platformy sprzętowej, bez konieczności pisania dużo kodu niskiego poziomu siebie.

Te biblioteki (w C) lub słowniki (w Forth) mogą zawierać niektóre funkcje lub słowa specyficzne dla sprzętu.

Euan M.
źródło