.tekst
Segment .text zawiera rzeczywisty kod i jest zaprogramowany w pamięci Flash dla mikrokontrolerów. Może istnieć więcej niż jeden segment tekstowy, gdy istnieje wiele nieciągłych bloków pamięci Flash; np. wektor startowy i wektory przerwań umieszczone na górze pamięci i kod rozpoczynający się od 0; lub oddzielne sekcje dla programu ładującego i programu głównego.
.bss i .data
Istnieją trzy rodzaje danych, które można przypisać zewnętrznie do funkcji lub procedury; pierwszy to niezainicjowane dane (historycznie nazywane .bss, które obejmuje również 0 zainicjowanych danych), a drugi to inicjalizacja (nie bss) lub .data. Nazwa „bss” historycznie pochodzi od „Block Started by Symbol”, używanego w asemblerze około 60 lat temu. Oba te obszary znajdują się w pamięci RAM.
Podczas kompilacji programu zmienne zostaną przypisane do jednego z tych dwóch ogólnych obszarów. Podczas etapu łączenia wszystkie elementy danych będą zbierane razem. Wszystkie zmienne, które należy zainicjować, będą miały część pamięci programu przeznaczoną do przechowywania wartości początkowych, a tuż przed wywołaniem funkcji main () zmienne zostaną zainicjowane, zwykle przez moduł o nazwie crt0. Sekcja bss jest inicjalizowana do wszystkich zer przez ten sam kod startowy.
Z kilkoma mikrokontrolerami dostępne są krótsze instrukcje, które umożliwiają dostęp do pierwszej strony (pierwsze 256 lokalizacji, czasami nazywanej stroną 0) pamięci RAM. Kompilator dla tych procesorów może zarezerwować słowo kluczowe, takie jak near
oznaczenie zmiennych, które mają zostać tam umieszczone. Podobnie istnieją również mikrokontrolery, które mogą odwoływać się tylko do niektórych obszarów za pośrednictwem rejestru wskaźników (wymagające dodatkowych instrukcji) i takie zmienne są oznaczone far
. Wreszcie, niektóre procesory mogą adresować sekcję pamięci bit po bicie, a kompilator będzie w stanie to określić (na przykład słowo kluczowe bit
).
Mogą więc istnieć dodatkowe segmenty, takie jak .nearbss i .neardata itp., W których gromadzone są te zmienne.
.rodata
Trzeci typ danych zewnętrznych względem funkcji lub procedury przypomina zmienne zainicjowane, z tym że są one tylko do odczytu i nie mogą być modyfikowane przez program. W języku C zmienne te oznaczone są za pomocą const
słowa kluczowego. Zazwyczaj są one przechowywane jako część pamięci flash programu. Czasami są one identyfikowane jako część segmentu .rodata (dane tylko do odczytu). Na mikrokontrolerach korzystających z architektury Harvarda kompilator musi użyć specjalnych instrukcji, aby uzyskać dostęp do tych zmiennych.
stos i stos
Stos i stos są umieszczone w pamięci RAM. W zależności od architektury procesora stos może rosnąć lub rosnąć. Jeśli dorośnie, zostanie umieszczony na dole pamięci RAM. Jeśli wzrośnie, zostanie umieszczony na końcu pamięci RAM. Sterta wykorzysta pozostałą pamięć RAM nieprzydzieloną do zmiennych i będzie rosła w przeciwnym kierunku do stosu. Maksymalny rozmiar stosu i sterty można zwykle określić jako parametry linkera.
Zmienne umieszczone na stosie to dowolne zmienne zdefiniowane w funkcji lub procedurze bez słowa kluczowego static
. Kiedyś nazywano je zmiennymi automatycznymi ( auto
słowo kluczowe), ale to słowo kluczowe nie jest potrzebne. Historycznie auto
istnieje, ponieważ był częścią języka B poprzedzającego C i tam był potrzebny. Parametry funkcji są również umieszczane na stosie.
Oto typowy układ pamięci RAM (przy założeniu braku specjalnej sekcji strony 0):
EEPROM, ROM i NVRAM
Zanim pojawiła się pamięć Flash, EEPROM (elektronicznie kasowalna programowalna pamięć tylko do odczytu) był używany do przechowywania programu i stałych danych (segmenty .text i .rodata). Teraz dostępna jest tylko niewielka ilość (np. 2 KB do 8 KB) pamięci EEPROM, o ile w ogóle jest dostępna, i jest zwykle używana do przechowywania danych konfiguracyjnych lub innych niewielkich ilości danych, które muszą zostać zachowane po wyłączeniu zasilania cykl. Nie są one deklarowane jako zmienne w programie, ale są zapisywane przy użyciu specjalnych rejestrów w mikrokontrolerze. EEPROM może być również zaimplementowany w osobnym układzie scalonym i dostępny za pośrednictwem magistrali SPI lub I²C.
Pamięć ROM jest zasadniczo taka sama jak Flash, tyle że jest programowana fabrycznie (nie programowalna przez użytkownika). Jest używany tylko w przypadku urządzeń o bardzo dużej głośności.
NVRAM (nieulotna pamięć RAM) jest alternatywą dla EEPROM i zwykle jest implementowana jako zewnętrzny układ scalony. Zwykła pamięć RAM może być uważana za nieulotną, jeśli jest zasilana z baterii; w takim przypadku nie są potrzebne żadne specjalne metody dostępu.
Chociaż dane można zapisywać we Flashu, pamięć Flash ma ograniczoną liczbę cykli kasowania / programów (od 1000 do 10 000), więc nie jest do tego specjalnie zaprojektowana. Wymaga również usunięcia bloków pamięci jednocześnie, więc aktualizowanie zaledwie kilku bajtów jest niewygodne. Jest przeznaczony do kodu i zmiennych tylko do odczytu.
EEPROM ma znacznie wyższe limity cykli kasowania / programów (od 100 000 do 1 000 000), więc jest znacznie lepszy w tym celu. Jeśli w mikrokontrolerze jest dostępna pamięć EEPROM i jest ona wystarczająco duża, tam właśnie chcesz zapisać nieulotne dane. Będziesz jednak musiał najpierw skasować bloki (zwykle 4KB) przed napisaniem.
Jeśli nie ma EEPROM lub jest za mały, potrzebny jest zewnętrzny układ. Pamięć EEPROM o pojemności 32 KB ma tylko 66 centów i można ją usunąć / zapisać do 1 000 000 razy. NVRAM z taką samą liczbą operacji kasowania / programu jest znacznie droższy (x10). NVRAM są zwykle szybsze do odczytu niż EEPROM, ale wolniejsze do zapisu. Mogą być zapisywane do jednego bajtu na raz lub blokami.
Lepszą alternatywą dla obu z nich jest FRAM (ferroelektryczna pamięć RAM), która ma zasadniczo nieskończone cykle zapisu (100 bilionów) i nie ma opóźnień zapisu. Ma mniej więcej tę samą cenę co NVRAM, około 5 USD za 32 KB.