Różnice między mikrokontrolerami

Tak w nawiązaniu do jednej ze wcześniejszych dyskusji:

Naukę programowania MCU zaczynałem od AVR, w międzyczasie przyjrzałem się trochę Arduino i ESP8266, teraz eksperymentuję z PIC32. W każdym przypadku korzystam z C/C++.

Po zapoznaniu się z tymi kilkoma przykładami odnoszę coraz większe wrażenie, że tak naprawdę nie ma wielkiej przepaści. Oczywiście - trzeba nauczyć się rzeczy charakterystycznych dla danej rodziny (taktowanie, timery, system przerwań, obsługa GPIO i interfejsów komunikacyjnych) ale tutaj można podeprzeć się datasheetami i podręcznikami. Potem na dobrą sprawę wygląda to całkiem podobnie - nawet biblioteki są te same albo opierają się na podobnych schematach - co najwyżej trzeba im tylko dostarczyć kilka niskopoziomowych funkcji.

Tak się zastanawiam - czy w przypadku korzystania z kompilatora C (załóżmy, że w ogóle nie bierzemy pod uwagę nauki asemblera) w pewnym momencie mogą pojawić się jakieś mocno specyficzne, sprzętowe różnice? Pomijam kwestię podstaw, np. wyrównywania zmiennych w pamięci albo rozmiarów typów. Czy jednak programowanie AVR, PIC, ARM7/ARM9 (od różnych producentów) czy STM32 nie różni się aż tak bardzo między sobą, gdy używa się C/C++?

Reply to
Atlantis
Loading thread data ...

Użytkownik "Atlantis" napisał w wiadomości grup dyskusyjnych:56b49564$0$642$ snipped-for-privacy@news.neostrada.pl...

Na poziomie C ? Istotnie, nie ma. Moze poza rodzina 8051 i jej obszarami danych :-)

Na poziomie assemblera ... z jednej strony sa olbrzymie, z drugiej - jak zrozumiales jak dziala jeden, to reszta dziala analogicznie.

To, plus wszystkie peryferia. Zegary, liczniki, przerwania, maski itp. A dalej roznice w bibliotekach - jak programujesz od zera to nie masz zadnych, jak korzystasz z dostarczonych przez kogos innego - wszelkie cuda mozliwe.

Zajrzyj chocby w zrodla jakiegos uni/linuxowego programu, ile tam roznych #if aby to dzialalo.

Obszary pamieci, zarzadzanie pamiecia - drobnych roznic jest pelno.

J.

Reply to
J.F.

oho Kolega dobił do momentu "wielka racjonalizacja donalda t." [R]

Reply to
platformowe głupki

Tak. Harvard vs von Neumann. De facto język C nie jest gotowy na operowanie w przestrzeni adresowej charakterystycznej dla Harvarda. Każde rozszerzenie załatwiające ten temat jest specyficzne dla konkretnego kompilatora i konkretnej arch. Były próby uwspólnienia tego w gcc ale wyszło jak zwykle.

Przy czym zaznaczam że czasami harvardowatość jest ukryta przed kodem usera. Mówimy o procesorach gdzie jest to widoczne, jak na przykład AVR. Tam jezyk C z definicji bedzie musiał być wspierany w mało przenośny sposób aby wydajnie programować.

Reply to
Sebastian Biały

W dniu 2016-02-05 o 18:47, Sebastian Biały pisze:

Hmm... O jakich aspektach kodu pod AVR tutaj mówimy?

Reply to
Atlantis

W dniu 05.02.2016 o 21:22, Atlantis pisze:

AVR ma oddzielną pamięć programu i danych co powoduje, że np do odczytania bajtu z pamięci programu (która ma szynę 16-bitową) służy inny rozkaz procesora niż do czytania bajtu z pamięci danych z szyną

8-bitową. Czyli jeśli z poziomu języka wyższego poziomu chcesz np. wyświetlić jakiś napis, to masz dwie różne definicje łańcucha określające w jakiej pamięci ma być umieszczony i dwie różne procedury do wyświetlania tego łańcucha w zależności gdzie był umieszczony. W AVRGCC jest specjalny typ wskaźnikowy do stałych umieszczonych w pamięci programu. Przy architekturze von Neumanna nie ma rozdzielenia pamięci danych od pamięci programu. O tym czy procesor widzi pamięć w danej chwili kostkę RAM, EPROM czy rejestr jakiegoś I/O decyduje dekoder adresów. Procek może wykonywać rozkazy umieszczone w dowolnym obszarze przestrzeni adresowej. Z punktu widzenia języka wysokiego poziomu w rodzaku C taki sam wskaźnik char* może wskazywać na jakiś fragment kodu programu, daną czy rejestr układu I/O.
Reply to
Grzegorz Kurczyk

On 2016-02-06 00:08, Grzegorz Kurczyk wrote: [...]

Tak dla uściślenia: MCU oparte o architekturę von Neumanna również mają oddzielne pamięci programu i danych ponieważ ta pierwsza jest zazwyczaj pamięcią nieulotną, a ta druga jest RAM-em. Chodzi o to, że w (zmodyfikowanej bądź nie) architekturze harwardzkiej pamięci danych i programu znajdują się w różnych przestrzeniach adresowych, a w architekturze von Neumanna te pamięci znajdują się w jednej, wspólnej przestrzeni adresowej. Z tego wynikają różne zady i walety tych architektur. W każdym razie rzeźbienie w C na MCU o architekturze harwardzkiej to trochę ból w dupie.

Reply to
JDX

W dniu 2016-02-06 o 00:08, Grzegorz Kurczyk pisze:

To jest oczywiste i faktycznie - jeśli biblioteka pisana pod AVR często korzysta z PROGMEM, to potem jej przeniesienie na PIC32 (albo nawet ośmiobitowe PIC-e, z uwagi na inną obsługę stałych we flashu) potrafi być nieco kłopotliwe. Niemniej nie jest to czymś, co wymagałoby jakiejś długiej nauki i zrozumienia skomplikowanych treści. ;)

Reply to
Atlantis

Dlaczego? Wystarczy zrobić #define PROGMEM i atrybut będzie zignorowany. Zobacz w Compiler.h jak to jest zrobione, ten sam kod w MLA może być kompilowany przez kompilatory

8/32 bit.Dla pic32 tego typu atrybuty stają się wtedy przezroczyste.
Reply to
Marek

A co zrobisz z pgm_read_float, pgm_read_byte i okolicą?

Reply to
Sebastian Biały

A jak wygląda kwestia układów ARM od różnych producentów? Istnieje jakiś standaryzowany sposób obsługi peryferiów, czy każdy producent narzuca swoje własne rozwiązania, w związku z czym nazwy i zawartość rejestrów/struktur są różne? Obsługa GPIO (z punktu widzenia kodu C) będzie podobna w takim LPC2000 i AT92SAM7, czy też będzie się całkowicie różnić?

Reply to
Atlantis

Mają zbliżoną architekturę CPU i zupełnie różne peryferia.

Nie. W miarę standardowy masz w jakiejś rodzinie. Bywa że wersja binarna kodu nie wymaga zmian po przeniesieniu na sąsiada. To głównie zasługa faktu że przestrzeń adresowa jest na tyle spora że nie trzeba co nową wersję pakować po nowemu IO.

Reply to
Sebastian Biały

A jak wygląda kwestia programatorów? STM32, STR91x, LPC2000, LPC1000, AT91SAM7, ATM91SAM9 i inne MCU na rdzeniach ARM/Cortex można programować i debugować jakimś jednym, standardowym JTAG-iem, czy też każdy producent/rodzina ma swoje własne, unikalne narzędzie?

Reply to
Atlantis

W dniu 2016-02-06 o 13:26, Atlantis pisze:

Cortexy mają taką próbę standaryzacji - Cortex® Microcontroller Software Interface Standard (CMSIS).

Reply to
Mario

W dniu 2016-02-06 o 15:29, Atlantis pisze:

Różnie. Każdy producent ma jakąś swoją firmę softwarową, która robi środowisko deweloperskie, zestawy uruchomieniowe i programatory dla danego producenta ARMów. Oprócz tego jest kilka firm robiących robiących takie rzeczy dla różnych producentów, ale podejrzewam ze nie mają jednego uniwersalnego programatora. Oprócz tego masz OpenOCD który współpracuje z różnymi programatorami, z których znaczna część to klony JtagKey Amonteca. Polecam OpenOCD. Ja dzięki niemu używam Jtag-Lock_Pick (Freddiego) do programowania Armów NXP i FPGA Xilinxa.

Reply to
Mario

Po co to, nie można tam wskaźnikiem lub tablicą?

Reply to
Marek

Obsluga pamięci ROM i RAM wymaga dwóch różnych instrukcji maszynowych. Dlatego istnieją makra i funkcje, ktore wymuszają traktowanie pointera do ROM a nie RAM. W harvardach ktore mają jeden typ wskaźnika (wiele ARMów) to zadanie wykonywane jest przez hardware dekodera adresów. W AVR nie ma takiego dekodera i kod sam decyduje czy wskaźnik jest do ROM czy RAM. To powoduje że sprawy nie da się łatwo załatwić makrem przy deklaracji pointera. Trzeba również w miejscu użycia wskazać do czego ten pointer jest.

Reply to
Sebastian Biały

maszynowych.

Ale to ja wiem, odpowiedz nie na temat. Pytam po co te pgm_costam? Jak user chce tabklice we flash to ustawia, jej specjalny atrybut przy definicji/deklaracji i to wszystko. A dalejj czyta ją przez tab[ndex] lub przez wskaźnik. Wewnetrznie kompilator wie z jakim rodzajem pamięci ma do czynienia i stosuje odpowiednie instrukcje. A jak chce się skompilować czymś co nie odróżnia atrybutów flash/ram robi się #define atrybut , który go "znika". Tak jest w picach. W ten sposób można swobodnie kompilować kod na architekturę, która nie odróżnia fkash/ram (np. z pic18 na pic32}.

Reply to
Marek

Intel x86 też ma oddzielnie segmenty kodu i danych. I co? I jakoś z tym żyjemy.

Intel x86 też ma oddzielne instrukcje mov i in.

Reply to
slawek

Nie. Mówisz o tym że x86 ma idiotyczny sposób uzywania wskaźników. Ale mimo tego idiotyzmu wskaźnik 0x1234:5678 jednoznacznie wskazuje na konkretna dana w konkretnej pamięci.

W przypadku AVR posiadanie wskaźnika 0x1234 uniemozliwia zgadnięcie czy to jest wskaźnik do ROM (adresowane od 0) czy do RAM (adresowane od 0). Dopiero fizyczna instrukcja ładowania danej określa jak go traktować.

Ale dotyczą one mało użytecznego mechanizmu I/O odziedziczonego jeszcze po 8080 gdzie niezwykle rzadko mówi się o "wskaźniku na rejestr IO". Raczej o ideksie. Pomińmy milczeniem wygłupy firmy Intel z okolic 8080 które miały zaoszczędzić na mmu po stronie implementacji. To głupie było. Inne procki z tamtych lat (np 6502) nie miały oddzielnej "pamięci IO" i świat się kręcił.

PS. Podpieranie się że x86 to von Neumann to troche zabawne jest, bo to procesor który nie da się chyba sklasyfikować z powodu swoich idiotyzmów. Weź 680x0 jako bardziej wzorcowy ;)

Reply to
Sebastian Biały

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.