Введение
Для встраиваемых систем управления, систем сбора и обработки данных, а также некоторых других приложений важна работа в реальном времени. Главное требование к такой системе заключается в выполнении условия детерминизма.
При этом гарантируется максимальное время задержки обработки прерывания или выполнения задачи. Это требование означает, что прерывание даже с самым низким приоритетом не зависнет, а будет обработано с задержкой, не превышающей заданного максимально допустимого значения, и не изменится временная последовательность событий.
Выполнение указанных требований достигается за счет использования операционных систем реального времени (ОСРВ). Одним из главных компонентов ОСРВ является планировщик задач, который обеспечивает распределение ресурсов микроконтроллера между задачами и исключает случайные задержки.
Пример простой детерминированной системы иллюстрирует рисунок 1, на котором выполнение основной задачи задача (Main) прерывается для обслуживания прерывания (ISR).
Рис. 1. Пример простой детерминированной системы
Прерывание возникает с периодичностью Т0 = Т1. Планировщик задач обеспечивает фиксированное время облуживания прерывания Е0 = Е1 = Е2. В противоположность детерминированной системе, в недетерминированной на рисунке 2 при той же периодичности прерываний Т0 = Т1 время, выделенное на обслуживание прерывания, заметно разнится Е0 != Е1 != Е2 (знак «!=» является эквивалентом оператора неравенства not_eq).
Рис. 2. Пример недетерминированной системы
Рисунок 3 поясняет сказанное. В случае пропуска кэша уровня L1 происходит обращение к кэшу уровня L2, а если и на этом уровне отсутствует требуемая команда, обращение следует уже к внешней памяти, например DDR. Во время этих операций прерывается работа конвейера выборки команд, возникает своеобразный джиттер на временной диаграмме выполнения ПО, упрощенный вариант которой показан на рисунке 1.
Рис. 3. Формирование джиттера на временной диаграмме выполнения ПО
Чем больше объем кэш-памяти, тем меньше случаев пропуска кэша, но полностью исключить их невозможно.
Дополнительным источником, затрудняющим деятельность планировщика, служит блок предсказания ветвлений, в котором также случаются ошибки; при этом конвейер приостанавливает работу. Во время процедуры обработки прерываний ISR в истории ветвлений содержатся данные, имеющие отношение к истории выполнения основного кода, а не к истории обработки прерываний. Таким образом, сбрасывается конвейер ISR. Иногда блок предсказания ветвлений можно отключить, но это уменьшает производительность, что может быть неприемлемым.
АрхитектураRISC—VPolarFire
Некоторые микроконтроллеры работают под Linux, но в них невозможно реализовать детерминизм. Существуют микроконтроллеры, которые способны реализовать детерминизм, но они не могут работать под Linux. С помощью архитектуры MicrochipRISC—VPolarFire можно решить обе задачи. Структурная схема СнК RISC—VPolarFire приведена на рисунке 4.
Рис. 4. Структурная схема СнК RISC—VPolarFire
четырехъядерный 64-бит модуль RV64GC RISC-V работает под Linux, а одноядерный модуль RV64IMAC такой возможности лишен. Еще одно отличие RV64GC состоит в том, что в его состав входит модуль операций с числами с плавающей запятой с двойной точностью. В модуле RV64GC имеется возможность отключить в любом ядре блок предсказания ветвлений. Эта процедура может осуществляться либо сразу при включении питания, либо при выполнении обработки прерывания (ISR). Кроме того, для всех ядер используются конвейеры, улучшающие детерминизм. Ядра защищены от атак Spectre и Meltdown.
Рассмотрим подсистему памяти, которая также важна для выполнения детерминизма. Память архитектуры отвечает условию когерентности, для выполнения которого предусмотрен специальный менеджер когерентности. Всего имеются три уровня памяти: L1, L2 и L3. В состав памяти L3 входит 36-бит контроллер, поддерживающий память типа LPDDR3/LPDDR4 и DDR3/DDR4.
Каждое из ядер RV64GC имеет тесно связанную память TIM, в которой организована 8-входовая 32-Кбайт ассоциативная кэш-память команд и такая же кэш-память данных. Ядру RV64IMAC Monitor принадлежит 2-входовая ассоциативная 16-Кбайт память TIM и память DTIM емкостью 8 Кбайт, в которой может храниться программный код. Тесно связанная память TIM уровня L1 обеспечивает быстрый доступ и поддерживает SECDED – исправление одиночной и двойной ошибок.
Память уровня L2 объемом 2 Мбайт поддерживает коррекцию SECDED и может конфигурироваться для работы в трех режимах: как 16-входовая ассоциативная кэш-память, слабосвязанная интегрированная память LIM и сверхоперативная регистровая память. В конфигурации LIM память можно «привязать» к процессору и разбить на блоки по 128 Кбайт. В этом случае подсистема памяти L2 обеспечивает детерминированный доступ ядру, к которому она «привязана». В этом случае она является когерентной, т.к. копии ее содержимого не используются в памяти уровней L1 и L3. Такой вариант конфигурации памяти хорошо соответствует условиям детерминизма, позволяя выполнять и главный код приложений, и обработку прерываний (ISR). Соответствующие пример показан на рисунке 5.
Рис. 5. Пример работы СнК ISC—VPolarFire при конфигурации памяти LIM
К сожалению, из-за ошибок в блоке предсказания ветвлений время выполнения процедур ISR все еще разнится, даже если память уровня L2 сконфигурирована в режиме LIM. На рисунке 6 показан пример реальной работы системы, когда память уровня L1 настроена как TIM, а память L2 – как LIM.
Рис. 6. Выполнение ISR при включенном блоке предсказания ветвлений
Время обработки прерываний, выраженное в циклах, отложено по вертикальной оси графика. Как видно из него, время выполнения прерываний меняется. Если отключить блок предсказания ветвлений, то картина разительно изменится (см. рис. 7).
Рис. 7. Выполнение ISR при выключенном блоке предсказания ветвлений
Как и в режиме LIM, в режиме сверхоперативного ЗУ память можно разбить на 128-Кбайт блоки и распределить их по отдельным процессорным ядрам. Например, если при такой конфигурации памяти ядро RV64IMAC записывает данные в память, а копия этой области существует в других областях памяти L1/L2/L3, то менеджер когерентности обеспечит целостность данных. Таким образом, при работе в реальном времени ядра, выполняющие разные приложения, могут согласованно обмениваться данными при работе под Linux.
На рисунке 8 показана одна из возможных конфигураций PolarFire.
Рис. 8. Пример конфигурации СнК PolarFire
При таком построении процессорное ядро RV64IMAC работает в реальном времени, а ядра RV64GC – под Linux. Если потребуются операции с числами с плавающей запятой, то используется RV64GC. При этом его блок предсказания ветвлений можно отключить, а память уровня L1 настроить в конфигурации TIM.
Выводы
Архитектура PolarFire за счет возможности конфигурирования подсистемы памяти, в отличие от многих микроконтроллеров, позволяет «мирно сосуществовать» и приложениям реального времени, и приложениям Linux. Инструменты для работы с PolarFire см. в [1].
Литература
1. www.microsemi.com.
Подписка: panovaid@yandex.ru