Udostępnij za pośrednictwem


Zarządzanie zagadnieniami dotyczących pamięci i opóźnień

W tym temacie opisano podstawowe zagadnienia dotyczące użycia pamięci i opóźnień w aplikacjach działających w czasie rzeczywistym na mikroukładie MT3620.

Uwaga

Aby uzyskać więcej szczegółowych informacji na temat konfiguracji pamięci lub DMA, zobacz opublikowany arkusz danych MT3620 firmy MediaTek. jeśli pytania pozostaną, możesz poprosić firmę Avnet o "arkusz danych MT3620 M4", wysyłając Azure.Sphere@avnet.comwiadomość e-mail.

Układ pamięci w rdzeniach w czasie rzeczywistym

W poniższej tabeli podsumowano pamięć dostępną w rdzeniach w czasie rzeczywistym:

Typ pamięci Adres podstawowy
TCM 0x00100000
Lampa błyskowa XIP 0x10000000
SYSRAM 0x22000000

Każdy rdzeń w czasie rzeczywistym ma 192 KB ściśle powiązanej pamięci (TCM), która jest mapowana w trzech bankach 64 KB, począwszy od 0x00100000. Dostęp do funkcji TCM jest szybki, ale tylko rdzeń w czasie rzeczywistym może uzyskiwać dostęp do pamięci. Funkcji TCM nie można udostępnić aplikacji wysokiego poziomu ani aplikacji obsługowej w czasie rzeczywistym (RTApp), która działa na innym rdzeniu.

Każdy rdzeń w czasie rzeczywistym ma również 64 KB pamięci SYSRAM, która jest mapowana od 0x22000000. Kontroler DMA może również kierować SYSRAM, aby urządzenia peryferyjne mogły uzyskać do niego dostęp. Dostęp do SYSRAM z rdzenia w czasie rzeczywistym jest wolniejszy niż dostęp do TCM. Podobnie jak WTM, SYSRAM nie może być udostępniany innej aplikacji.

Pamięć flash Execute-in-place (XIP) jest udostępniana aplikacjom wysokiego poziomu. Okno na mapowanie XIP lampy błyskowej jest widoczne dla każdego rdzenia pod adresem 0x10000000. System operacyjny konfiguruje mapowanie XIP przed uruchomieniem aplikacji, jeśli plik ELF aplikacji zawiera segment, który ma następujące właściwości:

  • Adres ładowania (określony w kolumnie VirtAddr nagłówka programu) jest równy 0x10000000
  • Przesunięcie i rozmiar pliku (określone w polach FileSiz i MemSiz w nagłówku programu) mieszczące się w pliku ELF aplikacji

Jeśli w pliku aplikacji ELF znajduje się nagłówek programu z tymi właściwościami, okno XIP zostanie umieszczone tak, aby segment był widoczny w 0x10000000. Plik może mieć nie więcej niż jeden segment XIP i musi wskazywać 0x10000000; nie może podać żadnego innego adresu.

Wdrożenie ELF

Obrazy RTApp muszą być plikami ELF. Obraz ELF jest zawinięty w pakiet obrazów Azure Sphere i wdrożony jako aplikacja. Aby załadować aplikację, system operacyjny Azure Sphere uruchamia moduł ładujący ELF, który działa na rdzeniu w czasie rzeczywistym. Moduł ładujący przetwarza każdy segment LOAD w pliku ELF i ładuje go do typu pamięci wskazanego przez adres wirtualny w nagłówku programu.

Użyj arm-none-eabi-readelf.exe -l (małe litery L), która jest częścią narzędzia GNU Arm Embedded Toolchain, aby wyświetlić nagłówki programów dla aplikacji. Wirtualna kolumna adresu (VirtAddr) wyświetlana w nagłówku wskazuje adres docelowy segmentu ładowania. Nie oznacza to, że sam procesor wykonuje jakiekolwiek dodatkowe tłumaczenie. Moduł ładujący AZURE Sphere ELF nie używa adresu fizycznego (PhysAddr).

Rozważmy ten przykład:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000098 0x00100000 0x00100000 0x00000 0x00e78 RW  0x8
  LOAD           0x0000a0 0x10000000 0x10000000 0x03078 0x03078 RWE 0x10
  LOAD           0x003118 0x00100e78 0x10003078 0x000f0 0x000f0 RW  0x4
  • Segment w 0x00100000 jest ukierunkowany na ściśle sprzężone pamięci (TCM). Moduł ładujący kopiuje dane z pakietu obrazów do pamięci RAM lub inicjuje moduł TCM w razie potrzeby.

  • Segment w 0x10000000 jest zamapowany na okno XIP rdzenia. W czasie wykonywania, dostęp do 0x10000000 + offset są tłumaczone <address-of-XIP-segment-in-flash> + offset po opuszczeniu rdzenia w czasie rzeczywistym.

  • Segment danych w 0x00100e78 adresu wirtualnego jest mapowany na TCM.

Zagadnienia dotyczące środowiska uruchomieniowego ELF

Moduł ładujący ELF wykonuje niektóre zadania, które w momencie uruchamiania wykonuje plik binarny (lub ładowarek łańcuchowy). W szczególności, to zero inicjuje block-started-by-symbol (BSS) dane i kopiuje zainicjowane, ale wyciszone dane z tylko do odczytu flash do pamięci RAM, zgodnie z nagłówkami programu. Następnie aplikacja uruchamia i uruchamia własne funkcje inicjowania. W większości przypadków zmiany w istniejących aplikacjach nie są wymagane. Zerowanie danych BSS w aplikacji jest niepotrzebne, ale nieszkodliwe, ponieważ moduł ładujący już wyzerował pamięć.

Kopiowanie zmiennych danych z lampy błyskowej do pamięci RAM może w pewnych okolicznościach powodować problemy w zależności od układu pliku ELF. Ładowarka ELF przetwarza nagłówki programu sekwencyjnie, bez zmiany ogólnego układu segmentów w pliku. Następnie mapuje nie tylko sam segment XIP na 0x10000000, ale także wszelkie kolejne segmenty w kolejności. Jeśli segmenty w pliku ELF są uporządkowane w kolejności bez wyrównania lub odstępów, kod uruchamiania systemu operacyjnego może znaleźć początek segmentu danych za pomocą arytmetyki wskaźnika. Jeśli jednak plik ELF ma inny układ, arytmetyka wskaźnika nie powoduje podania poprawnego adresu, dlatego kod uruchamiania aplikacji nie może próbować kopiować sekcji danych. Może to powodować problemy, jeśli aplikacja lub SYSTEM RTOS używa ładowarek łańcuchowych lub musi skonfigurować kanarek stosu przed zerowaniem BSS lub inicjowaniem danych z możliwością wyciszenia.

Elementy docelowe pamięci

Kod docelowy można kierować w witrynie TCM, XIP flash lub SYSRAM, edytują skrypt linker.ld dla twojej aplikacji. Przykładowe aplikacje Azure Sphere są uruchamiane z TCM, ale plik skryptu linker.ld dla każdej aplikacji opisuje, jak zamiast tego kierować lampę błyskową XIP. Jak pokazano w poniższym przykładzie, możesz zmienić przykład, aby uruchamiał się na xip, aliasując CODE_REGION i RODATA_REGION na FLASH zamiast domyślnego modułu TCM:

REGION_ALIAS("CODE_REGION", FLASH);
REGION_ALIAS("RODATA_REGION", FLASH);

Aby ustalić, czy skompilowana aplikacja działa z lampy błyskowej TCM lub XIP, użyj arm-none-eabi-readelf.exe, która jest częścią osadzonego narzędzia GNU Arm Toolchain. Uruchom go na pliku .out, który znajduje się w tym samym katalogu co pakiet obrazów, i określ -l flagę (małe litery L), aby zobaczyć, gdzie został umieszczony kod i dane tylko do odczytu. Kod i dane tylko do odczytu, które znajdują się w pamięci flash są ładowane pod adresem 0x10000000; kod i dane w funkcji TCM są ładowane w regionie TCM.

W poniższym przykładzie pokazano aplikację działającą z pamięci flash.

arm-none-eabi-readelf.exe -l UART_RTApp_MT3620_BareMetal.out

Elf file type is EXEC (Executable file)
Entry point 0x10000000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000074 0x00100000 0x00100000 0x00284 0x003c0 RW  0x4
  LOAD           0x000300 0x10000000 0x10000000 0x013b9 0x013b9 R E 0x10

 Section to Segment mapping:
  Segment Sections...
   00     .data .bss
   01     .text .rodata

Lokalizacja tabeli wektorów

W przypadku urządzeń ARMv7-M tabela wektorowa musi być wyrównana do granicy potęgi dwóch, która ma co najmniej 128 bajtów i nie mniejszą niż rozmiar tabeli, jak opisano w podręczniku obsługi architektury ARMv7-M. Każdy rdzeń we/wy RT na MT3620 obsługuje 100 przerwań zewnętrznych. W związku z tym, wraz ze wskaźnikiem stosu i 15 wyjątków standardowych, tabela ma 116 wpisów 4-bajtowych o łącznym rozmiarze 464 bajtów, co powoduje zaokrąglanie do 512 bajtów.

Po uruchomieniu kodu z lampy błyskowej XIP tabela wektorowa musi być umieszczona w 0x10000000 i musi być wyrównana do granicy 32-bajtowej w pliku ELF. Gdy kod nie jest uruchamiany z xip flash, tabela jest zazwyczaj umieszczana na początku TCM0, który jest 0x100000. W obu przypadkach, aby upewnić się, że wirtualny adres tabeli jest poprawnie wyrównany, umieść tabelę wektorową w dedykowanej sekcji i ustaw CODE_REGION na odpowiedni adres.

Przykłady platformy MT3620 BareMetal w repozytorium Próbki platformy Azure Sphere pokazują, jak to zrobić. Deklaracja tabeli wektorowej w komórce main.c ustawia jej section atrybut na .vector_table. Aliasy skryptów łączących CODE_REGION do początku programu TCM lub XIP, a atrybut ALIGN ustawia wyrównanie sekcji tekstowej w pliku ELF w następujący sposób:

SECTIONS
{
    .text : ALIGN(32) {
        KEEP(*(.vector_table))
        *(.text)
    } >CODE_REGION
...
}

Zagadnienia dotyczące czasu rzeczywistego i opóźnień

Aplikacje RTApps i aplikacje wysokiego poziomu walczą o dostęp do pamięci flash, nawet jeśli nie komunikują się ze sobą. W rezultacie aplikacje RTApps uruchomione z lampy błyskowej XIP mogą napotkać wysokie i nieprzewidywalne opóźnienia. Zapisy do flashowania, na przykład podczas aktualizacji, mogą obejmować skoki opóźnień do kilkuset milisekund. W zależności od wymagań aplikacji możesz nimi zarządzać na kilka sposobów:

  • Umieść wszystkie kody i dane w funkcji TCM. Kod, który działa z TCM nie jest podatny na rywalizację o flash.

  • Podziel kod na sekcje krytyczne i niekrytyczny i uruchom kod niekrytyczny z pamięci flash. Kod, który ma wymagania w czasie rzeczywistym, takie jak czasomierz watchdog, nie powinien być uruchamiany, gdy inny kod uzyskuje dostęp do lampy błyskowej. W obiektach docelowych pamięci opisano, jak kierować lampę błyskową XIP zamiast na moduł TCM.

  • Użyj pamięci podręcznej. Aplikacja może używać najmniejszej wartości 32 KB funkcji TCM jako pamięci podręcznej XIP. Ta metoda nie zapewnia twardych gwarancji w czasie rzeczywistym w przypadku pominięcia pamięci podręcznej, ale poprawia typową wydajność bez konieczności przenoszenia całego kodu na pamięć RAM. Informacje na temat konfiguracji pamięci podręcznej XIP można znaleźć w "arkuszu danych MT3620 M4".