Поделиться через


Рекомендации по управлению памятью и задержкой

В этом разделе описаны основные аспекты использования памяти и задержки для приложений в режиме реального времени, работающих на микросхеме MT3620.

Примечание

Дополнительные сведения о конфигурации памяти или DMA см. в опубликованной таблице MT3620 от MediaTek. Если остались вопросы, вы можете запросить "MT3620 M4 Datasheet" из Avnet, отправив по электронной Azure.Sphere@avnet.comпочте .

Макет памяти в ядрах в режиме реального времени

В следующей таблице перечислены объемы памяти, доступной для ядер в режиме реального времени.

Тип памяти Базовый адрес
TCM 0x00100000
Вспышка XIP 0x10000000
SYSRAM 0x22000000

Каждое ядро реального времени имеет 192 КБ тесно связанной памяти (TCM), которая сопоставляется в трех банках по 64 КБ, начиная с 0x00100000. Доступ к TCM выполняется быстро, но только ядро реального времени может получить доступ к памяти. TCM не может быть предоставлен совместно с приложением высокого уровня или приложением с поддержкой реального времени (RTApp), которое выполняется на другом ядре.

Каждое ядро в режиме реального времени также имеет 64 КБ SYSRAM, которое сопоставляется с 0x22000000. Контроллер DMA также может ориентироваться на SYSRAM, чтобы периферийные устройства могли получить к нему доступ. Доступ к SYSRAM из ядра реального времени выполняется медленнее, чем доступ к TCM. Как и в случае с TCM, SYSRAM не может использоваться другим приложением.

Флэш-память выполнения на месте (XIP) совместно используется приложениями высокого уровня. Окно в XIP-сопоставлении вспышки отображается для каждого ядра по адресу 0x10000000. ОС настраивает сопоставление XIP перед запуском приложения, если ELF-файл приложения содержит сегмент со следующими свойствами:

  • Адрес загрузки (как указано в столбце VirtAddr заголовка программы) равен 0x10000000
  • Смещение и размер файла (как указано в полях FileSiz и MemSiz в заголовке программы) помещаются в ELF-файл приложения.

Если заголовок программы с этими свойствами присутствует в ELF-файле приложения, окно XIP будет расположено таким образом, чтобы сегмент был виден на 0x10000000. Файл может содержать не более одного сегмента XIP и должен указывать на 0x10000000; он не может указать какой-либо другой адрес.

Развертывание ELF

Образы RTApp должны быть ELF-файлами. Образ ELF упаковывается в пакет образа Azure Sphere и развертывается как приложение. Чтобы загрузить приложение, ОС Azure Sphere запускает загрузчик ELF, который работает на ядре реального времени. Загрузчик обрабатывает каждый сегмент LOAD в ФАЙЛЕ ELF и загружает его в тип памяти, указанный виртуальным адресом в заголовке программы.

Используйте arm-none-eabi-readelf.exe -l (строчные буквы L), которая входит в цепочку инструментов GNU Arm Embedded, чтобы отобразить заголовки программы для приложения. Столбец виртуальных адресов (VirtAddr), отображаемый в заголовке, указывает целевой адрес для сегмента нагрузки. Это не означает, что процессор сам выполняет какой-либо дополнительный перевод. Загрузчик ELF в Azure Sphere не использует физический адрес (PhysAddr).

Рассмотрим следующий пример:

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
  • Сегмент в 0x00100000 предназначен для тесно связанной памяти (TCM). Загрузчик копирует данные из пакета образа в ОЗУ или при необходимости инициализирует TCM с нуля.

  • Сегмент на 0x10000000 сопоставляется с окном XIP для ядра. Во время выполнения доступы к 0x10000000 + offset претворяются <address-of-XIP-segment-in-flash> + offset в, когда они покидают ядро в режиме реального времени.

  • Сегмент данных на виртуальном адресе 0x00100e78 сопоставляется с TCM.

Рекомендации по выполнению ELF

Загрузчик ELF выполняет некоторые задачи, которые необработанный двоичный загрузчик (или цепной загрузчик) будет выполнять при запуске. В частности, она с нуля инициализирует данные BSS инициализирует инициализированные, но изменяемые данные из флэш-памяти только для чтения в ОЗУ в соответствии с заголовками программы. Затем приложение запускает и запускает собственные функции инициализации. В большинстве случаев изменения существующих приложений не требуются. Обнуление данных BSS в приложении является ненужным, но безвредным, так как загрузчик уже обнулил память.

Копирование изменяемых данных из флэш-памяти в ОЗУ в некоторых случаях может привести к проблемам в зависимости от того, как размещен ФАЙЛ ELF. Загрузчик ELF обрабатывает заголовки программы последовательно, не изменяя общий макет сегментов в файле. Затем он сопоставляет не только сам сегмент XIP с 0x10000000, но и все последующие сегменты по порядку. Если сегменты в файле ELF находятся в последовательном порядке без выравнивания или пробелов, код запуска ОС может использовать арифметические указатели, чтобы найти начало сегмента данных. Однако если elf-файл имеет другой макет, арифметика указателя не приводит к правильному адресу, поэтому код запуска приложения не должен пытаться скопировать раздел данных. Это может вызвать проблемы, если приложение или ОСРВ использует цепной загрузчик или необходимо настроить канареечные стеки перед обнуливанием BSS или инициализацией изменяемых данных.

Целевые объекты памяти

Вы можете нацелить код на TCM, флэш-память XIP или SYSRAM, изменив скрипт linker.ld для приложения. Примеры приложений Azure Sphere выполняются из TCM, но файл скрипта linker.ld для каждого приложения описывает, как использовать флэш-память XIP. Как показано в следующем примере, вы можете изменить пример для выполнения в XIP, указав псевдоним CODE_REGION и RODATA_REGION на FLASH, а не TCM по умолчанию:

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

Чтобы определить, выполняется ли скомпилированное приложение из флэш-памяти TCM или XIP, используйте arm-none-eabi-readelf.exe, которая является частью цепочки инструментов GNU Arm Embedded. Запустите его в out-файле, который находится в том же каталоге, что и пакет образа, и укажите -l флаг L в нижнем регистре, чтобы увидеть, где был размещен код и данные только для чтения. Код и данные, доступные только для чтения, которые находятся во флэш-памяти, загружаются по адресу 0x10000000; Код и данные в TCM загружаются в регионЕ TCM.

В следующем примере показано приложение, которое выполняется из флэш-памяти.

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

Расположение векторной таблицы

На устройствах ARMv7-M таблица векторов должна быть выровнена по границе power-of-two, которая составляет не менее 128 байт и не меньше размера таблицы, как указано в справочном руководстве по архитектуре ARMv7-M. Каждое ядро RT ввода-вывода в MT3620 поддерживает 100 внешних прерываний. Таким образом, включая указатель стека и 15 стандартных исключений, таблица содержит 116 4-байтовых записей общего размера в 464 байта, что округляет до 512 байт.

При выполнении кода из флэш-памяти XIP векторная таблица должна быть размещена на 0x10000000 и выровнена по 32-байтовой границе в ФАЙЛЕ ELF. Если код не выполняется из флэш-памяти XIP, таблица обычно размещается в начале TCM0, который 0x100000. В любом случае, чтобы убедиться, что виртуальный адрес таблицы правильно выравнивается, поместите таблицу векторов в выделенный раздел и задайте для CODE_REGION соответствующий адрес.

Примеры BareMetal MT3620 в репозитории примеров Azure Sphere показывают, как это сделать. Объявление векторной таблицы в main.c задает атрибуту section значение .vector_table. Псевдонимы скриптов компоновщика CODE_REGION в начале TCM или XIP, а атрибут ALIGN задает выравнивание текстового раздела в ФАЙЛЕ ELF следующим образом:

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

Рекомендации по работе в режиме реального времени и задержке

ПРИЛОЖЕНИЯ RTApp и приложения высокого уровня борются за доступ к флэш-памяти, даже если они не взаимодействуют друг с другом. В результате приложения RTApp, работающие на флэш-памяти XIP, могут столкнуться с высокой и непредсказуемой задержкой. Операции записи во флэш-память, например во время обновления, могут включать пики задержки до нескольких сотен миллисекундах. В зависимости от требований приложения вы можете управлять этим несколькими способами:

  • Поместите весь код и данные в TCM. Код, который выполняется из TCM, не уязвим для состязания за флэш-память.

  • Разделите код на критические и некритичные разделы и выполните некритичный код из флэш-памяти. Код с требованиями к режиму реального времени, например таймер сторожевой службы, не должен выполняться, когда другой код обращается к флэш-памяти. Целевые объекты памяти описывают, как нацеливать флэш-память XIP вместо TCM.

  • Использование кэша. Приложение может использовать наименьшие 32 КБ TCM в качестве кэша XIP. Этот подход не обеспечивает жестких гарантий в режиме реального времени в случае промаха кэша, но повышает типичную производительность, не требуя перемещения всего кода в ОЗУ. Сведения о конфигурации кэша XIP см. в таблице mt3620 M4.