Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek
Konsultacje: Wojciech Grodowski, mgr inż. Janusz Wałaszek

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

obrazek

Mikrokontrolery

ATmega8

Obsługa boot-loadera, samoprogramowanie

obrazek

Educational and Non-Profit Use of Copyrighted Material:

If you use Microchip copyrighted material solely for educational (non-profit) purposes falling under the “fair use” exception of the U.S. Copyright Act of 1976 then you do not need Microchip’s written permission. For example, Microchip’s permission is not required when using copyrighted material in: (1) an academic report, thesis, or dissertation; (2) classroom handouts or textbook; or (3) a presentation or article that is solely educational in nature (e.g., technical article published in a magazine).

https://www.microchip.com/about-us/legal-information/copyright-usage-guidelines

SPIS TREŚCI
Podrozdziały

obrazek

Cechy Boot-loadera

W artykule pojawia się kilka terminów angielskich, których postanowiłem nie tłumaczyć na język polski.
Boot-loader  – jest kodem uruchamianym w celu załadowania do pamięci FLASH programu aplikacji.
Sekcja boot-loadera  – jest to wydzielony obszar pamięci FLASH, w którym umieszczony został kod programowania pamięci FLASH.
Sekcja aplikacji  – jest to obszar pamięci FLASH, w którym jest umieszczony kod programu aplikacji. Obszar ten może być programowany przez boot-loader.
Read-While-Write (RWW)  – odczyt podczas zapisu. Jest to cecha pamięci FLASH, która umożliwia odczyt instrukcji dla mikroprocesora z pamięci FLASH, przy jednoczesnym programowaniu pamięci FLASH.
Read-Modify-Write  – odczyt, modyfikacja, zapis.
No-Read-While-Write (NRWW)  – jest to zablokowanie odczytu pamięci FLASH na czas jej programowania.

Wsparcie dla boot-loadera dostarcza rzeczywistego mechanizmu Read-While-Write samoprogramowania do ładowania i przesyłania kodu programu przez sam mikrokontroler. Cecha ta umożliwia elastyczne uaktualnienia aplikacji kontrolowane przez mikrokontroler używający umieszczonego w pamięci FLASH programu boot-loadera. Program ten może wykorzystywać dowolny z dostępnych interfejsów danych i powiązanego z nimi protokołu, aby odczytywać kod programu przesyłany z zewnątrz i zapisywać go w pamięci FLASH lub odczytywać kod programu z pamięci programu FLASH i przesyłać go na zewnątrz. Kod programu w obrębie sekcji boot-loadera posiada możliwość zapisu do całej pamięci FLASH, łącznie z sekcją boot-loadera. W ten sposób boot-loader może nawet modyfikować samego siebie i może również usunąć samego siebie z kodu, jeśli przestanie już być potrzebny. Rozmiar pamięci boot-loadera jest konfigurowalny za pomocą bitów bezpiecznikowych i boot-loader posiada dwa oddzielne zestawy bitów blokujących, które można ustawiać niezależnie. Daje to użytkownikowi unikalną elastyczność wyboru różnych poziomów zabezpieczeń.

Cechy boot-loadera są następujące:

Uwaga: 1. Strona jest sekcją w pamięci FLASH złożoną z kilku bajtów używaną podczas programowania. Organizacja stron nie wpływa na normalne działanie.

Na początek:  podrozdziału   strony 

Sekcje aplikacji i boot-loadera we FLASH

Pamięć FLASH jest zorganizowana w dwie główne sekcje: sekcję aplikacji i sekcję boot-loadera. Rozmiar różnych sekcji jest konfigurowany bitami bezpiecznikowymi BOOTSZ, co opisane jest dalej. Te dwie sekcje mogą posiadać różny poziom ochrony, ponieważ mają osobne zestawy bitów blokujących.

Sekcja aplikacji

Sekcja aplikacji jest częścią pamięci FLASH używaną do przechowywania kodu aplikacji. Poziom zabezpieczeń dla sekcji aplikacji można wybrać za pomocą bitów blokujących BLB0 (ang. Boot Lock Bits 0). Sekcja aplikacji nigdy nie może ładować żadnego kodu boot-loadera, ponieważ jest w niej zablokowane wykonywanie instrukcji SPM.

BLS – Sekcja boot-loadera

Podczas gdy sekcja aplikacji używana jest do przechowywania kodu aplikacji, to oprogramowanie boot-loadera musi być umieszczane w BLS, ponieważ instrukcja SPM może zainicjować programowanie tylko wtedy, gdy zostanie wykonana w obszarze BLS. Instrukcja SPM ma dostęp do całej pamięci FLASH, łącznie z BLS. Poziom zabezpieczeń dla sekcji boot-loadera można wybrać bitami blokującymi BLB1 (ang. Boot Lock Bits 1).


Na początek:  podrozdziału   strony 

Sekcje RWW i NRWW we FLASH

Czy mikroprocesor obsługuje opcję Read-While-Write, czy też jest wstrzymywany podczas uaktualniania oprogramowania boot-loadera, zależy od adresu, który jest programowany. Dodatkowo do dwóch sekcji konfigurowanych bitami bezpiecznikowymi BOOTSZ, jak opisano powyżej, pamięć FLASH jest również podzielona na dwie ustalone sekcje: sekcję Read-While-Write (RWW) oraz sekcję No-Read-While-Write (NRWW). Granica pomiędzy tymi dwoma sekcjami jest opisana dalej w tym rozdziale. Główną różnicą pomiędzy tymi dwoma sekcjami jest:

Zwróć uwagę, iż oprogramowanie użytkownika nigdy nie może odczytywać żadnego kodu, który jest umieszczony wewnątrz sekcji RWW podczas pracy oprogramowania boot-loadera. Zapis "sekcja Read-While-Write" odnosi się do tej sekcji, która jest programowana (wymazywana lub zapisywana), nie do sekcji, która jest rzeczywiście odczytywana podczas uaktualnienia oprogramowania boot-loadera.

RWW – Sekcja Read-While-Write

Gdy oprogramowanie boot-loadera programuje stronę wewnątrz sekcji RWW, możliwe jest odczytywanie kodu z pamięci FLASH, ale tylko kodu znajdującego się w sekcji NRWW. W czasie trwania programowania oprogramowanie musi zapewnić, że sekcja RWW nigdy nie jest odczytywana. Jeśli oprogramowanie użytkownika próbuje odczytywać kod znajdujący się wewnątrz sekcji RWW (tj. przez instrukcje call/rjmp/lpm lub jakieś przerwanie) podczas programowania, to oprogramowanie to może znaleźć się w nieokreślonym stanie. Aby uniknąć tego, przerwania powinny zostać albo wyłączone, albo przeniesione do sekcji boot-loadera, która zawsze jest umieszczona w sekcji NRWW. Bit zajętości sekcji RWW (ang.  RWW Section Busy bit, RWWSB) w rejestrze sterującym umieszczaniem w pamięci programu (ang. Store Program memory Control Register, SPMCR) będzie dawał odczyt logicznej jedynki tak długo, jak sekcja RWW jest zablokowana do odczytu. Po zakończeniu programowania bit RWWSB musi być wyzerowany przez oprogramowanie przed odczytem kodu umieszczonego w sekcji RWW. Zobacz do opisu rejestru SPMCR.

NRWW – Sekcja No-Read-While-Write

Kod umieszczony w sekcji NRWW może być odczytywany podczas uaktualniania strony w sekcji RWW przez oprogramowanie boot-loadera. Gdy kod boot-loadera uaktualnia sekcję NRWW, mikroprocesor zostaje zatrzymany podczas całej operacji wymazywania lub zapisu strony.

Cechy Read-While-Write

Którą sekcję adresuje wskaźnik Z podczas programowania? Która sekcja może być odczytywana podczas programowania Czy mikroprocesor jest zatrzymany? Obsługiwane Read-While-Write?
Sekcję RWW Sekcja NRWW Nie Tak
Sekcję NRWW żadna Tak Nie

Porównanie Read-While-Write z No-Read-While-Write

Sekcje pamięci


Na początek:  podrozdziału   strony 

Bity blokujące boot-loadera

Jeśli nie jest potrzebny program ładujący, to cała pamięć FLASH jest dostępna dla kodu aplikacji. Boot-loader posiada dwa oddzielne zestawy bitów blokujących, które mogą być ustawiane niezależnie. Pozwala to użytkownikowi elastycznie wybierać różne poziomy zabezpieczeń. Użytkownik może wybrać:

Szczegóły znajdziesz w poniższych tabelkach. Bity blokujące boot-loadera można ustawiać programowo oraz w trybie programowania szeregowego lub równoległego, lecz można je wymazać tylko przez polecenie kasowania układu (ang. chip erase command). Ogólna blokada zapisu (bit blokujący trybu 2) nie kontroluje programowania pamięci FLASH przez instrukcję SPM. Podobnie ogólna blokada odczytu/zapisu (bit blokujący trybu 3) nie kontroluje ani odczytu, ani zapisu przez instrukcje LPM/SPM, jeśli próbuje się to zrobić.

Tryby zabezpieczeń bitów blokujących 0 boot-loadera (sekcja aplikacji)
"1" oznacza bit niezaprogramowany, "0" oznacza bit zaprogramowany

Tryb BLB0 BLB02 BLB01 Zabezpieczenie
1 1 1 Nie ma ograniczeń na dostęp do sekcji aplikacji w instrukcjach LPM/SPM
2 1 0 Instrukcji SPM nie wolno zapisywać w sekcji aplikacji.
3 0 0 Instrukcji SPM nie wolno zapisywać w sekcji aplikacji, a instrukcji LPM wykonywanej w sekcji boot-loadera nie wolno odczytywać sekcji aplikacji. Jeśli wektory przerwań są umieszczone w sekcji boot-loadera, to przerwania są zablokowane przy wykonywaniu kodu z sekcji aplikacji.
4 0 1 Instrukcji LPM wykonywanej z sekcji boot-loadera nie wolno odczytywać sekcji aplikacji. Jeśli wektory przerwań są umieszczone w sekcji boot-loadera, to przerwania są zablokowane przy wykonywaniu kodu z sekcji aplikacji.

Tryby zabezpieczeń bitów blokujących 1 boot-loadera (sekcja boot-loadera)
"1" oznacza bit niezaprogramowany, "0" oznacza bit zaprogramowany

Tryb BLB1 BLB12 BLB11 Zabezpieczenie
1 1 1 Nie ma ograniczeń na dostęp do sekcji boot-loadera w instrukcjach LPM/SPM
2 1 0 Instrukcji SPM nie wolno zapisywać w sekcji boot-loadera.
3 0 0 Instrukcji SPM nie wolno zapisywać w sekcji boot-loadera, a instrukcji LPM wykonywanej w sekcji aplikacji nie wolno odczytywać sekcji boot-loadera. Jeśli wektory przerwań są umieszczone w sekcji aplikacji, to przerwania są zablokowane przy wykonywaniu kodu z sekcji boot-loadera.
4 0 1 Instrukcji LPM wykonywanej z sekcji aplikacji nie wolno odczytywać sekcji boot-loadera. Jeśli wektory przerwań są umieszczone w sekcji aplikacji, to przerwania są zablokowane przy wykonywaniu kodu z sekcji boot-loadera.

Na początek:  podrozdziału   strony 

Wchodzenie do programu boot-loadrera

Wejście do boot-loadera odbywa się przez skok lub wywołanie z programu aplikacji. Może to być wyzwalane rozkazem odebranym poprzez USART lub interfejs SPI. Alternatywnie można zaprogramować bit bezpiecznikowy Boot Reset, co spowoduje, że wektor resetu będzie wskazywał na początek sekcji boot-loadera w pamięci FLASH. W tym wypadku po resecie jest uruchamiany boot-loader. Po załadowaniu kodu aplikacji mikrokontroler może rozpocząć wykonywanie jej kodu. Zwróć uwagę, iż te bity bezpiecznikowe nie mogą być zmienione przez sam mikroprocesor. Oznacza to, iż po zaprogramowaniu raz bitu bezpiecznikowego Boot Reset wektor resetu będzie zawsze wskazywał na reset boot-loadera i bit ten możne jedynie zmienić poprzez interfejs programowania szeregowego lub równoległego.

Bit bezpiecznikowy Boot Reset
"1" oznacza bit niezaprogramowany, "0" oznacza bit zaprogramowany

BOOTRST Adres Resetu
1 Wektor resetu = Reset aplikacji (adres 0x0000)
0 Wektor resetu = Reset boot-loadera

SPMCR – Store Program Memory Control Register – Rejestr kontroli instrukcji SPM

Bit 7 6 5 4 3 2 1 0  
0x37 (0x57) SPMIE RWWSB RWWSRE BLBSET PGWRT PGERS SPMEN SPMCR
Zapis/Odczyt Z/O O O Z/O Z/O Z/O Z/O Z/O  
Wartość początkowa 0 0 0 0 0 0 0 0  

Bit 7 – SPMIE: SPM Interrupt Enable – Włączenie przerwania od instrukcji SPM

Gdy bit SPMIE zostanie zapisany jedynką i bit I w rejestrze stanu SREG jest ustawiony, to zostanie włączone przerwanie gotowości instrukcji SPM. Przerwanie to będzie wykonywane tak długo, jak bit SPMEN jest wyzerowany.

Bit 6 – RWWSB: Read-While-Write Section Busy – Zajętość sekcji RWW

Gdy zostanie zainicjowana operacja samoprogramowania (wymazywanie lub zapis strony) w sekcji RWW, bit RWWSB jest ustawiany (na jeden) sprzętowo. Gdy bit ten jest ustawiony, to nie ma dostępu do sekcji RWW. Bit RWWSB wyzeruje się, gdy do bitu RWWSRE zostanie wpisana jedynka po zakończeniu operacji samoprogramowania. Alternatywnie bit RWWSB jest automatycznie zerowany, gdy zostanie zainicjowana operacja ładowania strony.

Bit 5 – Bit zarezerwowany

Ten bit w ATmega8 jest zarezerwowany i przy odczycie zawsze zwraca zero.

Bit 4 – RWWSRE: Read-While-Write Section Read Enable – Włączenie odczytu sekcji RWW

Przy programowaniu (wymazywanie strony lub zapis strony) sekcji RWW jest ona zablokowana do odczytu (bit RWWSB będzie ustawiony sprzętowo). Aby z powrotem uaktywnić sekcję RWW, oprogramowanie użytkownika musi odczekać do zakończenia programowania (bit SPMEN zostanie wyzerowany). Wtedy, jeśli bit RWWSRE będzie zapisany w tym samym czasie co bit SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara uaktywni ponownie sekcję RWW. Sekcja RWW nie może być ponownie uaktywniona, gdy pamięć FLASH zajęta jest wymazywaniem strony lub zapisem strony (bit SPMEN ustawiony). Jeśli bit RWWSRE jest zapisywany w czasie, gdy pamięć FLASH jest ładowana, to operacja ładowania FLASH zostanie przerwana, a załadowane dane będą utracone (bufor strony zostanie wyzerowany przy ponownym uaktywnieniu sekcji RWW).

Bit 3 – BLBSET: Boot Lock Bit Set – Ustawianie bitów blokujących boot-loadera

Jeśli jedynka zostanie wpisana do tego bitu w tym samym czasie co do bitu SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara ustawi bity blokujące boot-loadera zgodnie z danymi w rejestrze R0. Dane w R1 i adres we wskaźniku Z są ignorowane. Bit BLBSET będzie automatycznie wyzerowany po zakończeniu ustawiania zestawu bitów blokujących lub jeśli w ciągu czterech cykli zegara nie będzie wykonana żadna instrukcja SPM.

Instrukcja LPM w ciągu trzech cykli zegarowych po ustawieniu bitów BLBSET i SPMEN odczyta albo bity blokujące, albo bity bezpiecznikowe (zależnie od bitu Z0 we wskaźniku Z) do rejestru docelowego.

Bit 2 – PGWRT: Page Write – Zapis strony

Jeśli jedynka zostanie wpisana do tego bitu w tym samym czasie co do SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara wykona zapis strony danymi umieszczonymi w buforze tymczasowym. Adres strony zostanie pobrany z górnej części wskaźnika Z. Dane w rejestrach R1 i R0 są ignorowane. Bit PGWRT bit wyzeruje się automatycznie po zakończeniu zapisu strony lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów zegarowych. Jeśli została zaadresowana sekcja NRWW, to mikroprocesor będzie wstrzymany przez całą operację zapisu strony.

Bit 1 – PGERS: Page Erase – Wymazywanie strony

Jeśli jedynka zostanie wpisana do tego bitu w tym samym czasie co do SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara wykona wymazanie strony. Adres strony zostanie pobrany z górnej części wskaźnika Z. Dane w rejestrach R1 i R0 są ignorowane. Bit PGERS bit wyzeruje się automatycznie po zakończeniu zapisu strony lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów zegarowych. Jeśli została zaadresowana sekcja NRWW, to mikroprocesor będzie wstrzymany przez całą operację wymazywania strony.

Bit 0 – SPMEN: Store Program Memory Enable – Włączenie instrukcji SPM

Ten bit włącza instrukcję SPM przez następne cztery takty zegarowe. Jeśli jedynka logiczna zostanie umieszczona w nim oraz w jednym z bitów RWWSRE, BLBSET, PGWRT lub PGERS, to następna instrukcja SPM będzie miała specjalne znaczenie, zobacz na opisy umieszczone powyżej. Jeśli będzie zapisany tylko sam bit SPMEN, to następna instrukcja SPM umieści wartość R1:R0 w tymczasowym buforze strony adresowanym przez wskaźnik Z. Najmłodszy bit, LSB, wskaźnika Z jest ignorowany. Bit SPMEN wyzeruje się automatycznie po zakończeniu instrukcji SPM lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu kolejnych czterech taktów zegarowych. Podczas wymazywania strony i zapisu strony bit pozostaje w stanie wysokim aż do zakończenia operacji.

Zapis innej kombinacji bitów niż “10001”, “01001”, “00101”, “00011” lub “00001” w dolnych pięciu bitach rejestru SPMCR nie wywołuje żadnego efektu.


Na początek:  podrozdziału   strony 

Adresowanie FLASH podczas samoprogramowania

Wskaźnik Z jest wykorzystywany w instrukcji SPM do adresowania.
Bit 15 14 13 12 11 10 9 8
ZH (R31) Z15 Z14 Z13 Z12 Z11 Z10 Z9 Z8
ZL (R30) Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0
Bit 7 6 5 4 3 2 1 0

Ponieważ pamięć FLASH jest zorganizowana w strony, to licznik programu (ang. Program Counter) można potraktować tak, jakby składał się z dwóch różnych sekcji. Jedna sekcja składająca się z najmniej znaczących bitów adresuje słowa wewnątrz strony, natomiast bity najbardziej znaczące adresują te strony. Pokazane to jest na poniższym rysunku. Zauważ, że operacje wymazywania strony (ang. page erase) i zapisu strony (ang. page write) używają osobnych adresów. Dlatego jest bardzo ważne, aby oprogramowanie boot-loadera adresowało tę samą stronę w obu tych operacjach. Gdy rozpocznie się programowanie, adres zostaje zapamiętany i wskaźnik Z może być użyty z innymi operacjami.

Jedyną operacją SPM, która nie używa wskaźnika Z, jest ustawianie bitów blokujących boot-loadera. Zawartość wskaźnika Z jest w nich ignorowana i nie wpływa na operację. Instrukcja LPM również korzysta ze wskaźnika Z do przechowywania adresu. Ponieważ ta instrukcja adresuje pamięć FLASH bajt po bajcie, to również bit LSB (bit Z0) wskaźnika Z jest używany.

obrazek


Na początek:  podrozdziału   strony 

Samoprogramowanie FLASH

Pamięć programu jest ładowana strona po stronie. Przed zaprogramowaniem strony danymi umieszczonymi w tymczasowym buforze strony, strona ta musi zostać wymazana. Bufor tymczasowy strony wypełniany jest kolejno słowami przy pomocy instrukcji SPM, a bufor ten można wypełniać albo przed rozkazem wymazania strony, albo pomiędzy operacjami wymazania strony i zapisu strony:

Alternatywa 1, wypełnij bufor przed wymazaniem strony

Alternatywa 2, wypełnij bufor po wymazaniu strony

Jeśli potrzeba zmienić tylko część strony, to reszta strony musi być zapamiętana np. w tymczasowym buforze strony przed wykonaniem operacji wymazania, a następnie ponownie zapisana. Jeśli używana jest alternatywa 1, to program ładujący (ang.  Boot Loader) udostępnia wygodną opcję odczytu-modyfikacji-zapisu, która pozwala programowi użytkownika najpierw odczytać stronę, dokonać niezbędnych zmian, a następnie zapisać z powrotem zmodyfikowane dane. Jeśli używana jest alternatywa 2, to nie jest możliwe odczytanie starych danych podczas ładowania, ponieważ strona została już wymazana. Tymczasowy bufor strony można zapisywać w dowolnej kolejności. Ważne jest, aby adres strony używany w obu operacjach wymazywania i zapisu był adresem tej samej strony.

Wymazywanie strony za pomocą instrukcji SPM

Aby wykonać wymazywanie strony, ustaw jej adres we wskaźniku Z, wpisz “X0000011” do rejestru SPMCR i wykonaj instrukcję SPM w ciągu czterech taktów zegarowych od momentu zapisu do SPMCR. Dane w rejestrach R1 i R0 są ignorowane. Adres strony musi zostać wpisany do pola PCPAGE we wskaźniku Z. Pozostałe bity wskaźnika Z zostaną zignorowane podczas tej operacji.

Uwaga: Jeśli podczas czasowej sekwencji wystąpi przerwanie, to dostęp w ciągu czterech taktów nie jest gwarantowany. Aby zapewnić operację atomową (niepodzielną czasowo), wyłącz przerwania przed zapisem do rejestru SPMCSR.

Wypełnianie bufora tymczasowego (ładowanie strony)

Aby zapisać słowo instrukcji, ustaw adres we wskaźniku Z i dane w rejestrach R1:R0, wpisz “00000001” do rejestru SPMCR i wykonaj instrukcję SPM w ciągu czterech taktów zegarowych od momentu zapisu do SPMCR. Zawartość pola PCWORD we wskaźniku Z jest używana do adresowania danych w tymczasowym buforze strony. Bufor ten automatycznie wyzeruje się po operacji zapisu strony lub po zapisie bitu RWWSRE w rejestrze
SPMCR. Jest on również wymazywany po resecie systemowym. Zwróć uwagę, iż nie jest możliwe zapisanie każdego adresu więcej niż raz bez wymazywania bufora tymczasowego.

Uwaga: Jeśli pamięć EEPROM będzie zapisywana w środku operacji ładowania strony instrukcją SPM, to wszystkie załadowane dane zostaną utracone.

Wykonywanie zapisu strony

Aby wykonać zapis strony, ustaw jej adres we wskaźniku Z, wpisz “X0000101” do rejestru SPMCR i wykonaj instrukcję SPM w ciągu czterech taktów zegarowych od momentu zapisu do SPMCR. Dane w rejestrach R1 i R0 są ignorowane. Adres strony musi zostać wpisany do pola PCPAGE we wskaźniku Z. Pozostałe bity wskaźnika Z zostaną zignorowane podczas tej operacji.

Wykorzystywanie przerwania od instrukcji SPM

Jeśli przerwanie od SPM zostało uaktywnione, to będzie ono generowało ciągłe przerwanie, gdy bit SPMEN w rejestrze SPMCR zostanie wyzerowany. Oznacza to, iż zamiast programowego monitorowania stanu rejestru SPMCR można użyć tego przerwania. Gdy używane jest przerwanie od SPM, wektory przerwań należy przenieść do sekcji boot-loadera, aby uniknąć sytuacji, iż przerwanie próbuje uzyskać dostęp do sekcji RWW, gdy jest ona zablokowana przed odczytem. Sposób przenoszenia przerwań opisano w rozdziale "Przerwania".

Ostrożność przy ładowaniu sekcji boot-loadera

Należy podjąć specjalne kroki ostrożności, jeśli użytkownik zezwoli na uaktualnianie sekcji boot-loadera przez pozostawienie w stanie niezaprogramowanym bitu blokującego BL11. Przypadkowy zapis boot-loadera do swojego własnego kodu może uszkodzić cały boot-loader i dalsze uaktualnienia oprogramowania mogą stać się niemożliwe. Jeśli nie jest konieczne zmienianie oprogramowania boot-loadera przez sam boot-loader, to zaleca się zaprogramowanie bitu blokującego BL11, aby chronić oprogramowanie boot-loadera przez jakąkolwiek wewnętrzną zmianą oprogramowania.

Zapobieganie odczytowi sekcji RWW podczas samoprogramowania

Podczas samoprogramowania (wymazywanie strony lub zapis strony) sekcja RWW jest zawsze zablokowana przed odczytem. Oprogramowanie użytkownika musi samo zapobiegać adresowaniu tej sekcji podczas operacji samoprogramowania. Bit RWWSB w rejestrze SPMCR będzie ustawiony tak długo, jak sekcja RWW jest zajęta. Podczas samoprogramowania tablica wektorów przerwań powinna być przeniesiona do sekcji boot-loadera, jak opisano w rozdziale "Przerwania", lub przerwania należy wyłączyć. Przed zaadresowaniem sekcji RWW po zakończeniu jej programowania oprogramowanie użytkownika musi wyzerować bit RWWSB przez zapis do RWWSRE.

Ustawianie bitów blokujących boot-loadera przy pomocy instrukcji SPM

Aby ustawić bity blokujące boot-loadera, wpisz pożądane dane do rejestru R0, wpisz “X0001001” do rejestru SPMCR i wykonaj instrukcję SPM w ciągu czterech taktów zegarowych po wpisie do SPMCR. Dostępne są jedynie bity blokujące boot-loadera, które mogą zapobiec uaktualnianiu oprogramowania przez mikrokontroler w sekcji aplikacji i w sekcji boot-loadera.

Bit 7 6 5 4 3 2 1 0
R0  1   1  BLB12 BLB11 BLB02 BLB01  1   1 

Poniższe tablice przedstawiają wpływ ustawień tych bitów na programowanie pamięci FLASH.

Tryby zabezpieczeń bitów blokujących 0 boot-loadera (sekcja aplikacji)
"1" oznacza bit niezaprogramowany, "0" oznacza bit zaprogramowany

Tryb BLB0 BLB02 BLB01 Zabezpieczenie
1 1 1 Nie ma ograniczeń na dostęp do sekcji aplikacji w instrukcjach LPM/SPM
2 1 0 Instrukcji SPM nie wolno zapisywać w sekcji aplikacji.
3 0 0 Instrukcji SPM nie wolno zapisywać w sekcji aplikacji, a instrukcji LPM wykonywanej w sekcji boot-loadera nie wolno odczytywać sekcji aplikacji. Jeśli wektory przerwań są umieszczone w sekcji boot-loadera, to przerwania są zablokowane przy wykonywaniu kodu z sekcji aplikacji.
4 0 1 Instrukcji LPM wykonywanej z sekcji boot-loadera nie wolno odczytywać sekcji aplikacji. Jeśli wektory przerwań są umieszczone w sekcji boot-loadera, to przerwania są zablokowane przy wykonywaniu kodu z sekcji aplikacji.

Tryby zabezpieczeń bitów blokujących 1 boot-loadera (sekcja boot-loadera)
"1" oznacza bit niezaprogramowany, "0" oznacza bit zaprogramowany

Tryb BLB1 BLB12 BLB11 Zabezpieczenie
1 1 1 Nie ma ograniczeń na dostęp do sekcji boot-loadera w instrukcjach LPM/SPM
2 1 0 Instrukcji SPM nie wolno zapisywać w sekcji boot-loadera.
3 0 0 Instrukcji SPM nie wolno zapisywać w sekcji boot-loadera, a instrukcji LPM wykonywanej w sekcji aplikacji nie wolno odczytywać sekcji boot-loadera. Jeśli wektory przerwań są umieszczone w sekcji aplikacji, to przerwania są zablokowane przy wykonywaniu kodu z sekcji boot-loadera.
4 0 1 Instrukcji LPM wykonywanej z sekcji aplikacji nie wolno odczytywać sekcji boot-loadera. Jeśli wektory przerwań są umieszczone w sekcji aplikacji, to przerwania są zablokowane przy wykonywaniu kodu z sekcji boot-loadera.

Jeśli bity 5...2 w R0 są wyzerowane, to odpowiadające im bity blokujące boot-loadera zostaną zaprogramowane, jeśli instrukcja SPM będzie wykonana w przeciągu czterech taktów po ustawieniu bitów BLBSET i SPMEN w rejestrze SPMCR. Zawartość wskaźnika Z jest ignorowana podczas tej operacji, lecz dla przyszłej kompatybilności zaleca się wpisanie do Z wartości 0x001 (takiej samej, jaką używa się przy odczycie bitów blokujących). Dla przyszłej kompatybilności zaleca się również ustawienie bitów 7, 6, 1 i 0 w rejestrze R0 na jeden przy zapisywaniu bitów blokujących. Przy programowaniu bitów blokujących cała pamięć FLASH może być odczytywana podczas tej operacji.

Zapis pamięci EEPROM zapobiega zapisowi do SPMCR

Zauważ, iż operacja zapisu pamięci EEPROM zablokuje wszelkie programowanie pamięci FLASH. Odczyt bitów bezpiecznikowych i blokujących z poziomu oprogramowania jest również zablokowany podczas operacji zapisu EEPROM. Zaleca się sprawdzanie bitu stanu EEWE w rejestrze EECR i upewnieniu się, iż jest on wyzerowany, przed zapisywaniem rejestru SPMCR.

Programowy odczyt bitów bezpiecznikowych i blokujących

Możliwy jest programowy odczyt zarówno bitów bezpiecznikowych jak i bitów blokujących. Aby odczytać bity blokujące, załaduj wskaźnik Z wartością 0x0001 i ustaw bity BLBSET i SPMEN w rejestrze SPMCR. Gdy w ciągu trzech taktów mikroprocesora po tej operacji zostanie wykonana instrukcja LPM , to wartość bitów blokujących zostanie załadowana do rejestru docelowego. Bity BLBSET i SPMEN wyzerują się automatycznie po zakończeniu odczytu bitów blokujących lub jeśli  żadna instrukcja LPM nie będzie wykonana w ciągu trzech taktów mikroprocesora lub żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów mikroprocesora.  Gdy bity BLBSET i SPMEN wyzerują się, instrukcja LPM będzie działać zgodnie z opisem.

Bit 7 6 5 4 3 2 1 0
Rd  –   –  BLB12 BLB11 BLB02 BLB01  LB2  LB1

Algorytm odczytu dolnych bitów bezpiecznikowych jest podobny do algorytmu opisanego powyżej dla odczytu bitów blokujących. Aby odczytać dolne bity bezpiecznikowe, załaduj wskaźnik Z wartością 0x0000 i ustaw bity BLBSET i SPMEN w rejestrze SPMCR. Gdy instrukcja LPM zostanie wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN w SPMCR, wartość dolnych bitów bezpiecznikowych (FLB) będzie załadowana do rejestru docelowego, jak pokazano poniżej.

Bit 7 6 5 4 3 2 1 0
Rd FLB7  FLB6 FLB5 FLB4 FLB3 FLB2 FLB1 FLB0

Podobnie przy odczycie górnych bitów bezpiecznikowych załaduj wskaźnik Z wartością 0x0003. Gdy instrukcja LPM zostanie wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN w SPMCR, wartość górnych bitów bezpiecznikowych (FHB) będzie załadowana do rejestru docelowego, jak pokazano poniżej.

Bit 7 6 5 4 3 2 1 0
Rd FHB7  FHB6 FHB5 FHB4 FHB3 FHB2 FHB1 FHB0

Zaprogramowane bity bezpiecznikowe i blokujące mają przy odczycie stan zero, natomiast bity niezaprogramowane dają przy odczycie stan jeden.

Zapobieganie uszkodzeniu danych w pamięci FLASH

W okresach spadku napięcia zasilającego VCC programowanie pamięci FLASH może zakończyć się błędami, ponieważ napięcie zasilające jest zbyt niskie, aby mikroprocesor i pamięć FLASH pracowały poprawnie. Problemy te są takie same jak w systemach z zewnętrzną pamięcią FLASH i należy stosować te same rozwiązania projektowe. Błędy programowania FLASH mogą pojawić się w dwóch sytuacjach, gdy napięcie jest za niskie. Po pierwsze standardowa sekwencja zapisu do FLASH wymaga minimalnego napięcia do poprawnej pracy. Po drugie, sam mikroprocesor może wykonywać instrukcje niepoprawnie, jeśli napięcie zasilające jest dla nich zbyt niskie.

Błędom w FLASH można łatwo zapobiec stosując się do następujących zaleceń projektowych (jedno jest wystarczające):

  1. Jeśli nie ma potrzeby uaktualniania boot-loadera w systemie, zaprogramuj bity blokujące boot-loadera, tak aby zapobiec uaktualnianiu jego oprogramowania.
  2. Utrzymuj linię AVR RESET w stanie aktywnym (niskim) w okresach niewystarczającej wartości napięcia zasilającego. Można tego dokonać poprzez włączenie wewnętrznego detektora spadku napięcia zasilania (ang. internal Brown-out Detector, BOD), jeśli napięcie pracy pasuje do poziomu wykrywania. Jeśli nie, można użyć zewnętrznego układu resetowania przy niskim napięciu VCC. Jeśli reset wystąpi podczas wykonywania operacji zapisu, to operacja ta zostanie zakończona pod warunkiem, iż napięcie zasilające posiada wystarczającą wartość.
  3. Utrzymuj rdzeń AVR w trybie uśpienia z wyłączeniem zasilania (ang. Power-down sleep mode) w okresach niskiego VCC. Uniemożliwi to mikroprocesorowi próby dekodowania i wykonywania instrukcji, co skutecznie zabezpieczy rejestr SPMCSR, a co za tym idzie również pamięć FLASH, przed niezamierzonymi zapisami.


Czas programowania FLASH przy użyciu instrukcji SPM

Kalibrowany oscylator RC jest używany do odmierzania czasu dostępów do pamięci FLASH. Poniższa tabela pokazuje typowy czas programowania FLASH przy dostępie przez mikroprocesor.

Symbol Min. czas programowania Max. czas programowania
Zapis FLASH (wymazywanie strony, zapis strony i zapis bitów blokujących przez SPM) 3,7 ms 4,5 ms

Prosty przykład w asemblerze boot-loadera

  ;-Procedura zapisuje jedną stronę danych z RAM do FLASH
  ; Pierwszy adres danych w RAM jest wskazywany przez wskaźnik Y
  ; Pierwszy adres danych we FLASH jest wskazywany przez wskaźnik Z
  ;-Obsługa błędów nie została zrealizowana
  ;-Procedura musi się znaleźć w obszarze boot-loadera
  ; (przynajmniej podprogram Do_spm). Tylko kod wewnątrz sekcji NRWW może
  ; być odczytywany podczas samoprogramowania (wymazywania strony i zapisu strony).
  ;-Używane rejestry: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
  ; loophi (r25), spmcrval (r20)
  ; W procedurze nie zastosowano zachowywania i odtwarzania rejestrów.
  ; Wykorzystanie rejestrów można zoptymalizować kosztem rozmiaru kodu.
  ;-Zakłada się, iż albo tablica przerwań została przeniesiona do sekcji
  ; boot-loadera, albo przerwania są wyłączone.
.equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB jest rozmiarem strony w bajtach, nie w słowach
.org SMALLBOOTSTART
Write_page:
  ; Wymazywanie strony
  ldi spmcrval, (1<<PGERS) | (1<<SPMEN)
  rcall Do_spm
  ; Ponowne uaktywnienie sekcji RWW
  ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
  rcall Do_spm
  ; Przenieś dane z RAM do bufora strony FLASH
  ldi looplo, low(PAGESIZEB) ;Inicjuj zmienną pętli
  ldi loophi, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256
Wrloop:
  ld r0, Y+
  ld r1, Y+
  ldi spmcrval, (1<<SPMEN)
  rcall Do_spm
  adiw ZH:ZL, 2
  sbiw loophi:looplo, 2 ;Użyj subi dla PAGESIZEB<=256
  brne Wrloop
  ; Wykonaj zapis strony
  subi ZL, low(PAGESIZEB) ;Odtwórz wskaźnik
  sbci ZH, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256
  ldi spmcrval, (1<<PGWRT) | (1<<SPMEN)
  rcall Do_spm
  ; Ponowne uaktywnienie sekcji RWW
  ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
  rcall Do_spm
  ; Odczytaj z powrotem i sprawdź, opcjonalne
  ldi looplo, low(PAGESIZEB) ;Inicjuj zmienną pętli
  ldi loophi, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256
  subi YL, low(PAGESIZEB) ;Odtwórz wskaźnik
  sbci YH, high(PAGESIZEB)
Rdloop:
  lpm r0, Z+
  ld r1, Y+
  cpse r0, r1
  rjmp Error
  sbiw loophi:looplo, 1 ;Użyj subi dla PAGESIZEB<=256
  brne Rdloop
  ; Wróć do sekcji RWW
  ; Sprawdź, czy odczyt sekcji RWW jest bezpieczny
Return:
  in temp1, SPMCR
  sbrs temp1, RWWSB ;Jeśli bit RWWSB jest ustawiony, sekcja RWW nie jest jeszcze gotowa
  ret
  ; Ponowne uaktywnienie sekcji RWW
  ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
  rcall Do_spm
  rjmp Return
Do_spm:
  ; Sprawdź zakończenie poprzedniej instrukcji SPM
Wait_spm:
  in temp1, SPMCR
  sbrc temp1, SPMEN
  rjmp Wait_spm
  ; Wejście: spmcrval określa działanie SPM
  ; Wyłącz przerwania, jeśli są włączone, zachowaj stan
  in temp2, SREG
  cli
  ; Sprawdź, iż nie następuje zapis do EEPROM
Wait_ee:
  sbic EECR, EEWE
  rjmp Wait_ee
  ; Sekwencja czasowa SPM
  out SPMCR, spmcrval
  spm
  ; Odtwórz SREG (aby włączyć przerwania, jeśli oryginalnie były włączone)
  out SREG, temp2
  ret

Parametry boot-loadera w ATmega8

Poniższe tabele podają parametry używane w opisach samoprogramowania.

Konfiguracja rozmiaru sekcji boot-loadera

BOOTSZ1 BOOTSZ0 Rozmiar sekcji boot-loadera Strony Sekcja FLASH aplikacji Sekcja FLASH boot-loadera Koniec sekcji aplikacji Adres Resetu w sekcji boot-loadera
1 1 128 słów 4 0x000 - 0xF7F 0xF80 - 0xFFF 0xF7F 0xF80
1 0 256 słów 8 0x000 - 0xEFF 0xF00 - 0xFFF 0xEFF 0xF00
0 1 512 słów 16 0x000 - 0xDFF 0xE00 - 0xFFF 0xDFF 0xE00
0 0 1024 słów 32 0x000 - 0xBFF 0xC00 - 0xFFF 0xBFF 0xC00

Granica sekcji RWW

Sekcja Strony Adres
RWW 96 0x000 - 0xBFF
NRWW 32 0xC00 - 0xFFF

Wyjaśnienie różnych zmiennych używanych do opisu dostępu do pamięci FLASH przy pomocy wskaźnika Z

Zmienna   Odpowiadająca wartość Z(1) Opis
PCMSB 11   Najbardziej znaczący bit licznika programu (licznik programu ma długość 12 bitów PC[11:0]).
PAGEMSB 4   Najbardziej znaczący bit używany do adresowania słów wewnątrz strony (32 słowa na stronie wymagają 5 bitów PC[4:0]).
ZPCMSB   Z12 Bit w rejestrze Z, który odwzorowuje PCMSB. Ponieważ bit Z0 nie jest używany, to ZPCMSB równe jest PCMSB + 1.
ZPAGEMSB   Z5 Bit w rejestrze Z, który odwzorowuje PAGEMSB. Ponieważ bit Z0 nie jest używany, to ZPAGEMSB równe jest PAGEMSB + 1.
PCPAGE PC[11:5] Z12:Z6 Adres strony dla licznika programu: wybór strony dla operacji wymazywania strony i zapisu strony.
PCWORD PC[4:0] Z5:Z1 Adres słowa dla licznika programu: wybór słowa przy wypełnianiu bufora tymczasowego (musi mieć wartość zero podczas operacji zapisu strony).
Uwaga: 1. Bity Z15:Z13: są zawsze ignorowane.
Bit Z0: powinien mieć wartość zero dla wszystkich rozkazów SPM, w instrukcji LPM wybiera bajt.
Szczegóły używania wskaźnika Z przy samoprogramowaniu znajdziesz w podrozdziale "Adresowanie FLASH podczas samoprogramowania".

Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2024 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.