poniedziałek, 24 października 2016

Stos oraz sterta w mikrokontrolerach

W tym poście chciałbym opisać co to takiego jest stos a co to jest sterta.

Stos:


Stos jest to pewien obszar pamięci, który jest adresowany za pomocą przeznaczonego do tego rejestru wskaźnikowe. Na stos operacje wprowadzone są w sposób standardowy tzn. element ostatnio odłożony będzie jako pierwszy z niego ściągany. 


Do stosu dane są wprowadzone z użyciem polecenia PUSH natomiast ściągane POP. Obie operacje wpływają na rejestr R13, odpowiednio zmniejszając albo zwiększając jego wartości. Każda wartość na stosie jest 8 bitowa. W związku z tym wartości tego rejestru dla mikrokontrolerów 32 bitowych jest zwiększana bądź zmniejszana o 4.

R13 (Stack Pointer SP) jest wskaźnikiem i na aktualną wartość jednego ze stosów. Może on wskazywać na dwa stosy systemowe tzn. na MSP(Main Stack Pointer) bądź PSP(Process Stack Pointer). To na który rejestr nastąpi wskazywanie danych ustawia się za pomocą rejestru CONTROL, domyślnie tym stosem jest MSP. Który jest domyślnie wykorzystywany w przerwaniu.


Do ustawienia w rejestrze CONTROL jest tylko bit 1 ASPSEL. Domyślna wartość 0 wskazuje na MSP, po wprowadzeniu 1 wskazanie następuje na PSP. 

W przerwaniu stos przechowuje ważne informacje dotyczące rejestrów systemowych, po wyjściu dane są z niego zdejmowane, dzięki temu układ może swobodnie wrócić do normalnej pracy. Jeśli korzysta się także z PSP to to jest on wykorzystywany do przechowywania informacji o 

Na stosie ogólnie mogą być przechowywane elementy takie jak: zmienne lokalne, argumenty wywołane dla funkcji, wartość jaka może być zwracana przez funkcję, adres wywołania funkcji w kodzie.

Jeśli układ będzie pracował w trybie uprzywilejowanym to można korzystać z obu stosów bezpośrednio z wykorzystaniem instrukcji assemblera (MRS - odczyt, MSR - zapis), bądź z użyciem odpowiednio opracowanych makr: do odczytu - __MRS_PSP() oraz zapisu __MSR_PSP(32 bitowa wartość do wprowadzenia). Dla MSP wygląda to analogicznie tylko zamiana PSP na MSP. 

Sterta:


Jest to rodzaj pamięci jaka jest udostępniana przez system operacyjny wszystkim działającym programom czy procesom. Służy ona do przechowywania dynamicznie tworzonych struktur danych oraz dla dynamicznie przydzielanych obszarów pamięci.

W mikrokontrolerach można dobrać wartości pamięci jakie zostały przeznaczone na stos oraz na stertę. Wartości te dopiera się korzystając z pliku dla startup-u. Natomiast zwykle jest to dokonywane poprzez dobranie wartości stosu, pamięci statycznej, zostaje przeznaczone na stertę. Domyślnie kod programu będzie wczytywany z pamięci flash, której jest w mikrokontrolerze najwięcej, i nie jest ona kasowana. 

Jeśli przejdziemy teraz do rezerwowania pamięci czyli metody statycznej. To oznacza, że pamięć zostaje zarezerwowana, właściwie zawsze z nadkładem, w momencie kompilacji kodu źródłowego. Ułatwia to obsługę pamięci oraz upraszcza zapis, natomiast zajmuje zasoby nadwyrost przez co możne to ograniczyć możliwości kodu.

W przypadku dynamicznego przydzielania pamięci w trakcie działania programu uzyskuje się kontrolę oraz dosyć dużą elastyczność dotyczącą obsługi pamięci. Wykorzystywana jest tylko taka jej ilość jaka jest potrzebna. Co do minusów to istnieje możliwość wycieków pamięci oraz jej fragmentacji.