RC-51-0.pdf

(147 KB) Pobierz
Microsoft Word - Modele pamiêci_v1-3.doc
http://www.easy-soft.tsnet.pl
Kompilatory języka C przeznaczone dla mikrokontrolerów z rodziny 8051 oferują szereg
różnych modeli pamięci. Który z nich wybrać? Jakie kryteria wyboru stosować? Jaki
wpływ ma zastosowany model kompilacji na optymalizację kodu wynikowego oraz czas
wykonywania programu przez mikrokontroler?
Konfiguracja pamięci mikrokontrolera 8051 dla programów
napisanych w języku C.
Podstawy: fizyczne lokalizacje segmentów pamięci.
Prawdopodobnie najbardziej irytującym podczas konstrukcji pierwszych urządzeń z
mikrokontrolerem z rodziny 8051 oraz tworzenia dla nich programów jest fakt, że
posiada on kilka różnych obszarów pamięci zaczynających się od tego samego adresu.
Inne mikrokontrolery, dla przykładu z rodziny 68HC11, mają pojedynczą przestrzeń
adresową, w której poszczególne obszary pamięci umieszczone są sekwencyjnie jeden za
drugim, w zależności od tego, czy istnieją w danym urządzeniu, czy też nie. Jest to
zgodne z konfiguracją pojedynczego obszaru pamięci według Von Neuman’a. W
mikrokontrolerze 8051 pamięć podzielono na szereg segmentów dostępnych różnymi
technikami. Aby dobrze zrozumieć zasady użycia poszczególnych rodzajów pamięci i
modeli kompilacji, musimy przyjrzeć się bliżej temu podziałowi i miejscom fizycznej
lokalizacji komórek pamięci.
Pierwszy z segmentów nazywa się DATA . Mowa tu o wewnętrznej pamięci RAM
mikrokontrolera zwanej segmentem danych. Zaczyna się on od adresu 0x00 * i kończy
pod adresem 0x7F (127 dziesiętnie). Główne przeznaczenie tego segmentu pamięci to
przechowywanie zmiennych wykorzystywanych przez program w czasie pracy. Obszar ten
dostępny jest jako adresowany bezpośrednio. Znajdą tu zastosowanie instrukcje
asemblera z grupy MOV A,n – MOV n,A.
Od adresu 0x80 umieszczony jest tak zwany rejestr funkcji specjalnych SFR (Special
Function Register), który również może być adresowany bezpośrednio. Powyżej adresu
0x80, do adresu 0xFF, rozciąga się część drugiego obszaru pamięci RAM zwany IDATA ,
który może być adresowany wyłączenie pośrednio. Znajdują tu zastosowanie instrukcje z
grupy MOV A,@Ri (i=0 lub i=1).
Podstawowa architektura mikrokontrolera 8051 wyposażona była w 128 bajtów pamięci
DATA. Dodatkowy segment IDATA pojawił się w momencie konstrukcji mikrokontrolerów
z rodziny 8052. Segment ten nie jest częścią pamięci DATA. Rozciąga się od adresu 0x00
do 0xFF i może być adresowany wyłącznie pośrednio. Z związku z tym dobrze jest
stosować go nie w celu zapamiętywania zmiennych ale z przeznaczeniem na stos
mikrokontrolera. CPU będzie wtedy używał tego segmentu adresując go za
pośrednictwem wskaźnika stosu. Oczywiście pisząc programy w C raczej nie mamy
wpływu na to, do czego kompilator będzie wykorzystywał obszar IDATA. Opisaną tutaj
zasadę należy stosować pisząc programy w języku asembler.
Obszar IDATA nakłada się na obszar rejestru SFR. Jawnie widać tu pewną sprzeczność:
IDATA dzielący wspólnie przestrzeń adresową z SFR może być adresowany tylko
pośrednio, natomiast do SFR mają dostęp instrukcje adresowania bezpośredniego! Aby
było ciekawiej, oba te segmenty znajdują się w obszarze wewnętrznej pamięci RAM
mikrokontrolera. Czyli patrząc na to od strony programisty 8051 – to do jakiego obszaru
pamięci zapisywane czy z jakiego odczytywane są dane, zależy od sposobu w jaki
zostanie zaadresowany ten sam obszar pamięci. Ten sam w znaczeniu fizycznie
wpisywanego adresu, nie zaś segmentu pamięci mikrokontrolera. Pomoże to zrozumieć
poniższy fragment programu asemblerowego:
MOV 0A0H,#dana ;zapis do obszaru SFR, w tym przypadku do P2
;(równoznaczny zapis to MOV P2,#dana)
MOV R0,#0A0H
MOV @R0,#dana ;zapis do obszaru IDATA (nie do P2!)
Pierwsza linia przykładowego programu zapisuje dane do obszaru SFR, w tym przypadku
jest to port P2. Druga i trzecia linia, mimo iż powodują zapis bajtu pod ten sam adres, to
J.Bogusz „Konfiguracja pamięci dla programów napisanych w języku C”, Strona 1 z 8
305448310.003.png
http://www.easy-soft.tsnet.pl
jednak używane jest adresowanie pośrednie (adresowanie przy pomocy rejestru R0) i
bajt zostaje zapisany w segmencie IDATA a nie jak poprzednio w SFR. Warto o tym
pamiętać tworząc własne aplikacje.
Trzeci segment pamięci, nazywany CODE , również rozpoczyna się od adresu 0x0000 ale
zarezerwowany jest na pamięć programu. Typowo obszar ten zajmuje adresy od 0x0000
do 0xFFFF (65536 bajtów) i jeśli używany jest mikrokontroler 8031, to segment ten w
całości podłączany jest z zewnątrz w postaci dodatkowego układu pamięci ROM. Niektóre
mikrokontrolery, np. 8051, posiadają jednak wewnętrzną pamięć ROM, pełniącą tę samą
rolę. Segment pamięci programu dostępny jest przez instrukcje wykorzystujące do
adresowania licznik rozkazów PC oraz 16-bitowy rejestr DPTR. Oczywiście w segmencie
CODE mogą być przechowywane wyłącznie wartości stałe takie, jak tablice danych a
przede wszystkim instrukcje programu wykonywanego przez mikrokontroler.
Czwarty segment pamięci, nazywany XDATA (czasami można się spotkać z określeniem
XRAM ), również znajduje się poza mikrokontrolerem. Zaczyna się od adresu 0x0000 i
tak, jak segment CODE, kończy się pod adresem 0xFFFF. Jedna uwaga: omawiając
przestrzeń adresową pamięci CODE czy XDATA opisuję możliwość jej fizycznego
rozszerzenia a nie przymus zajmowania całego dostępnego obszaru przez dane
urządzenie (układ) podłączone w tej przestrzeni adresowej.
W zestawie rozkazów 8051 można znaleźć tylko jedną metodę dostępu do całego
segmentu XDATA za pomocą pojedynczego rozkazu. Służą do tego instrukcje
wykorzystujące do adresowania rejestr DPTR. Nie mniej jednak cały obszar XDATA (od
adresu 0x0000 do 0xFFFF) może być też dostępny w trybie stronicowania. Do
adresowania pamięci w obszarze 256-bajtowej strony jest tu używany ośmiobitowy
rejestr R0 lub R1. W tym przypadku starszą część adresu (numer strony) trzeba ustawić
„ręcznie” np. poprzez wpisanie odpowiedniej wartości do P2. Trzeba przy tym pamiętać,
że P2 nie bierze aktywnego udziału podczas takiego adresowania (nie pełni funkcji szyny
systemowej). Równie dobrze może być wykorzystany inny rejestr lub nawet tylko jego
część. Obszar ten nazywany jest PDATA.
Pojawia się pytanie: w jaki sposób CPU mikrokontrolera 8051 rozróżnia fizycznie inne i o
innym przeznaczeniu obszary pamięci? W jaki sposób kod instrukcji programu pobierany
jest spod adresu CODE:0x0000 zamiast DATA:0x00? Odpowiedź tkwi w konstrukcji
mikrokontrolera. Gdy CPU żąda dostępu do segmentu DATA, załączany jest wewnętrzny
RAM przez wewnętrzny sygnał odczytu READ – jego odpowiednik wyprowadzany na
zewnątrz (wyprowadzenie READ mikrokontrolera) pozostaje bez zmian.
Odczyt i zapis bajtu z wykorzystaniem akumulatora w trybie adresowania
bezpośredniego:
MOV A,40H ;odczyt bajtu spod adresu 0x40
MOV 40H,A ;zapis bajtu pod adres 0x40
Jest to podstawowy tryb dla modelu pamięci SMALL.
J.Bogusz „Konfiguracja pamięci dla programów napisanych w języku C”, Strona 2 z 8
305448310.004.png
http://www.easy-soft.tsnet.pl
Odczyt bajtu z wykorzystaniem trybu adresowania pośredniego z segmentu IDATA za
pośrednictwem akumulatora i rejestru R0
MOV R0,#0A0H
;odczyt bajtu z segmentu IDATA znajdującego się pod adresem
MOV A,@R0
;0xA0 do akumulatora
Ten tryb adresowania używany jest do dostępu do pośrednio adresowanych komórek
pamięci IDATA leżących powyżej 0x80 i jest alternatywną metodą dostępu do danych
leżących poniżej tego adresu.
W obrębie segmentu DATA znajduje się również obszar nazywany BDATA. Jest to
szesnaście bajtów (128 bitów) zajmujących przestrzeń adresową od 0x20 do 0x2F w
obszarze adresowania bezpośredniego. Specjalną cechę tego obszaru stanowi fakt, że
oprócz instrukcji MOV mają zastosowanie również instrukcje operujące na pojedynczych
bitach i wykorzystujące specjalny tryb adresowania pojedynczych bitów.
Zewnętrzna pamięć ROM (segment CODE) nie jest załączana podczas dostępu do RAM
czy XDATA (XRAM). Jej wyborem steruje sygnał PSEN (Program Store Enable) – zmiana
poziomu wyprowadzenia PSEN na niski uaktywnia pamięć programu. Nazwa
wyprowadzenia sygnału jest jednocześnie sugestią, że główną rolą pamięci ROM jest
przechowywanie instrukcji programu.
Pewną ciekawostkę stanowi fakt, że jeśli mikrokontroler posiada wewnętrzną pamięć
ROM (FLASH, EPROM) to w cyklu dostępu do tej pamięci, stan zewnętrznego
wyprowadzenia PSEN nie zmienia się dotąd, aż przekroczony zostanie obszar
adresowania wewnętrznego ROM. Po tym fakcie – mikrokontroler wykonuje normalny
cykl dostępu do zewnętrznej pamięci programu wyprowadzając przez porty P0 i P2
adresy oraz pobierając instrukcje do wykonania z zewnętrznej pamięci ROM. W takiej
sytuacji, jeśli zewnętrzna pamięć ROM ulokowana jest od adresu 0x0000, to bajty leżące
poniżej końca adresu wewnętrznej pamięci ROM (na przykład dla 4kB będzie to adres
0x1000) nie będą dostępne.
Podłączone do mikrokontrolera z zewnątrz segmenty XDATA oraz CODE nie są ze sobą w
konflikcie. Ich rozdział jest przeprowadzany przez zewnętrzne sygnały sterujące. Jak
wcześniej wspomniałem, dostęp do obszaru CODE aktywowany jest przy pomocy PSEN.
Dostępem do obszaru XDATA sterują zewnętrzne sygnały READ (odczyt) i WRITE (zapis).
Wyprowadzenie PSEN nie bierze udziału w cyklu dostępu do danych zawartych w
segmencie XDATA.
Aby odróżnić polecenia dostępu do danych zawartych w segmencie XDATA od
pozostałych, wprowadzono specjalne instrukcje zawierające w swej nazwie literę X
MOV DPTR,#08000H
;zapamiętaj daną zawartą w akumulatorze pod adresem
MOVX A,@DPTR
;0x8000 w pamięci XDATA
Ten alternatywny tryb dostępu do pamięci XDATA jest podstawowym dla modelu
COMPACT. Zauważ, że jeśli Port 2 podłączony jest do starszych linii adresowych, może on
pracować jako przełączany przez aplikację kontroler stron pamięci.
Istotną do zapamiętania informacją jest to, że wyprowadzenie PSEN przyjmuje stan niski,
jeśli pobierany jest kod instrukcji, natomiast wyprowadzenia READ i WRITE podczas
wykonywania przez CPU rozkazu MOVX. Litera X w symbolu polecenia języka asembler
mikrokontrolera 8051 oznacza rozkaz związany z urządzeniem podłączonym z zewnątrz,
aktywowanym przy pomocy READ lub WRITE.
Dostępne modele pamięci.
Pisząc program dla mikrokontrolera 8051 pierwsza decyzja, którą musisz podjąć to taka,
jaki model pamięci wybierzesz. Podczas gdy programista komputera PC dokonuje wyboru
J.Bogusz „Konfiguracja pamięci dla programów napisanych w języku C”, Strona 3 z 8
305448310.005.png 305448310.006.png
http://www.easy-soft.tsnet.pl
pomiędzy modelami TINY, SMALL, MEDIUM, COMPACT, LARGE i HUGE aby kontrolować
jak używane są segmenty pamięci RAM komputera PC, programista 8051 planujący
swoją aplikację, musi podjąć decyzję na podstawie tego, gdzie znajdują się dane
niezbędne podczas pracy mikrokontrolera.
Popularnie używane kompilatory Keil i Raisonance aktualnie obsługują następujące
konfiguracje pamięci:
1. ROM. Największy rozmiar zbioru obiektu, który może powstać po kompilacji, to
64kB, jakkolwiek znacznie większe rozmiary pamięci ROM (do 1MB - kompilator
Keil, do 4MB - kompilator Raisonance) mogą być obsługiwane w trybie
przełączanych banków pamięci (BANKED) opisanym w dalszej części artykułu.
Zmienne mogą być deklarowane przy użyciu słowa kluczowego code
umieszczającego je w pamięci programu mikrokontrolera. Nazwa zmienne jest tu
myląca, ponieważ zadeklarowana na przykład tablica, może pełnić rolę wzorca –
nigdy zaś zmiennej.
2. RAM. Dostępne są trzy modele pamięci: SMALL, COMPACT i LARGE.
o SMALL. Wszystkie zmienne zostają umieszczone w wewnętrznej pamięci
mikrokontrolera
o COMPACT. Zmienne zostają zapamiętane w segmencie pamięci PDATA,
adresowanej przez port P0 (z bankami przełączanymi przez P2). Używany
jest tryb adresowania pośredniego. Wewnętrzne rejestry mikrokontrolera
są w dalszym ciągu używane do przechowywania lokalnych zmiennych i
parametrów.
o LARGE. Zmienne i parametry przechowywane są w zewnętrznej pamięci
adresowanej za pośrednictwem @DPTR. Wewnętrzne rejestry
mikrokontrolera w dalszym ciągu używane są do przechowywania
zmiennych i parametrów.
3. BANKED (przełączane banki pamięci). Program może zajmować do 1MB -
kompilator Keil lub 4MB - kompilator Raisonance. Pamięć przełączana jest w
formie „stron” o rozmiarze 64kB każda przy pomocy innych niż właściwe dla P0 i
P1 wyprowadzeń mikrokontrolera albo też za pomocą zatrzasków latch
umieszczonych w przestrzeni adresowej, powyżej adresu 0xFFFF. Każdy 64kB blok
pamięci programu musi posiadać ustawiony tak zwany blok wspólny (COMMON
AREA) dla biblioteki funkcji przełączającej banki pamięci.
Firma Raisonance wprowadziła do swojego kompilatora dodatkowy model pamięci TINY,
który jest identyczny z modelem SMALL z tym, że podczas kompilowania programu
generowane są instrukcje ACALL i AJMP zamiast LCALL i LJMP. Limituje to rozmiar
obszaru pamięci programu do 2kB i jest użyteczne szczególnie dla mikrokontrolerów,
które nie obsługują lub nie potrzebują instrukcji LCALL i LJMP, mających do 2kB pamięci
ROM w swojej strukturze (AT89C2051, 87C751 itp.) oraz nie posiadających na zewnątrz
wyprowadzeń PSEN, READ i WRITE. W Keilu można korzystać z dyrektywy ROM. Np.
#PRAGMA ROM(SMALL) spowoduje używanie wyłącznie rozkazów ACALL i AJMP.
Możliwe jest również łączenie poszczególnych modeli pamięci tak, aby zmusić kompilator
do lokowania zmiennych i danych w określonych segmentach pamięci, pod określonym
adresem.
Wybór najlepszego modelu pamięci.
Model TINY nie nastręcza żadnych trudności przy wyborze. Stosuje się go raczej do
bardzo małych programów. Dla większości aplikacji wykonywanych dla mikrokontrolera
8051 wystarczający jest model SMALL. Stosując go można również używać zewnętrznej
pamięci znajdującej się w segmencie PDATA. Dostęp do niej uzyskuje się za pomocą
instrukcji MOVX A,@Ri i MOVX @Ri,A
SMALL - pamięć RAM, 128 bajtów
Używając modelu SMALL, należy zredukować do minimum liczbę zmiennych globalnych
używanych w programie. Pozwoli to programowi linkera na nakładkowanie funkcji w taki
J.Bogusz „Konfiguracja pamięci dla programów napisanych w języku C”, Strona 4 z 8
305448310.001.png
http://www.easy-soft.tsnet.pl
sposób, aby aplikacja pracowała efektywnie. Dla mikrokontrolerów z serii 8052 / 8032
deklaracje zmiennych w przestrzeni IDATA powyżej adresu 0x80 mogą pozwolić aplikacji
na uzyskanie dodatkowej przestrzeni do przechowywania zmiennych. Należy jednak
pamiętać, że obszar ten używany jest również na stos mikrokontrolera.
Model SMALL można także stosować przy kompilacji nawet bardzo dużych programów,
umieszczając obiekty duże i takie, do których nie jest wymagany bardzo szybki dostęp, w
zewnętrznej pamięci RAM. Dobrze jest tam również ulokować zmienne, które muszą być
dostępne w czasie rzeczywistym podczas uruchamiania urządzenia z mikrokontrolerem
przy pomocy emulatora, ponieważ emulatory (takie jak produkowane przez Hitex albo
Raisonance) mają bezpośredni dostęp do tego segmentu pamięci. Ten model najlepszy
jest również dla aplikacji o krytycznym czasie wykonywania, jako że gwarantuje on
najszybszy dostęp do zmiennych i parametrów przez funkcje, podczas gdy duże obszary
danych mogą zostać umieszczone poza układem mikrokontrolera.
COMPACT - pamięć RAM 256 bajtów poza układem, 128 lub 256 bajtów w
układzie.
COMPACT to model pamięci dostosowany do programów, gdzie dla przykładu wewnętrzny
RAM mikrokontrolera przeznaczony jest na zmienne systemu operacyjnego. Model ten
jest rzadko używany dla całego programu. Najbardziej użyteczna kombinacja to jego
połączenie z modelem SMALL używanym lokalnie dla procedur obsługi przerwań.
COMPACT stosuje się przede wszystkim do programów zawierających dużą liczbę
zmiennych, które nie wymagają krótkiego czasu dostępu. Odbywa się on bowiem za
pomocą instrukcji MOVX A,@Ri wykorzystującej tryb adresowania pośredniego przy
pomocy rejestru R0 lub R1. COMPACT może być również bardzo użyteczny dla aplikacji
wymagających stosu o dużym rozmiarze, co może oznaczać konieczność umieszczenia go
w zewnętrznej pamięci RAM poza układem mikrokontrolera.
LARGE - pamięć RAM do 64kB poza układem, 128 lub 256 bajtów w układzie.
Model LARGE pozwala na niezbyt szybki dostęp do bardzo dużego obszaru pamięci RAM i
jest przypuszczalnie najłatwiejszym do użycia. Podobnie jak poprzednio, niezbyt często
używa się go w odosobnieniu – raczej w połączeniu z modelem SMALL. Tak jak w
COMPACT, nadal używane są rejestry mikrokontrolera.
Wybór optymalnego segmentu dla danych.
Podsumowując: mikrokontroler 8051 oferuje pięć segmentów pamięci dostępnych dla
danych, z których każdy ma swoje pewne specyficzne cechy. Oto kilka wskazówek, do
jakich zastosowań najlepiej używać każdego z nich.
Nazwa segmentu
pamięci
Zalecany do...
Nie zalecany do...
DATA
Rozmiar 128
bajtów, domyślny
dla modelu SMALL.
Często używanych danych
wymagających szybkiego
dostępu.
Procedur obsługi przerwań,
które powinny być
wykonywane bardzo szybko,
powinny używać obszaru
DATA, poprzez lokalną
deklarację funkcji jako
stosującej model SMALL.
Często wywoływany
podprogramów pobierających
czy przekazujących dużą
liczbę parametrów.
Stosu funkcji typu re-entrant .
Zmiennych tablicowych i
struktur zawierających więcej
niż kilka – kilkanaście bajtów.
J.Bogusz „Konfiguracja pamięci dla programów napisanych w języku C”, Strona 5 z 8
305448310.002.png
Zgłoś jeśli naruszono regulamin