Flash и RAM: выполнение кода


13

Недавно я начал изучать ассемблер и узнал о скриптах компоновщика и других низкоуровневых деталях аппаратного программирования. Я также учу себя компьютерной архитектуре, и где-то вдоль линии я начал бояться, что моя картина модели памяти могла быть неправильной с самого начала.

В соответствии с тем, что я понимаю в настоящее время, весь код и данные находятся в энергонезависимой памяти сразу после того, как мы «запишем» двоичный файл в процессор - энергозависимая оперативная память ничего не содержит при перезагрузке. Когда программа начинает «выполняться», она делает это с адреса 0x0000, который почти всегда (AFAIK) является самым низким адресом во Flash. Таким образом, инструкции привязаны к шине, соединяющей Flash с ядром процессора, и именно здесь происходит фактическое выполнение. Тем не менее, когда мы говорим о том, что процессор извлекает или хранит данные из памяти, мы обычно говорим об оперативной памяти - я осознаю, что мы можем также читать / записывать данные из памяти программы (я видел это на AVR) но разве это не так распространено? Это потому, что оперативная память быстрее ПЗУ, что мы предпочитаем хранить там данные?

Принятый ответ на этот вопрос говорит о том, что большая часть кода выполняется из ОЗУ.

Означает ли это, что код времени запуска (который сам исполняется из Flash) должен копировать все коды операций программы из Flash в RAM и каким-то образом отображать адреса во Flash так, чтобы они указывали на RAM, чтобы процессор выбирал коды операций оттуда? Это похоже на процесс, в котором мы перемещаем разделы .data из ROM в RAM при запуске?

Я могу себе представить, что это проще в архитектурах фон Неймана, где память программ и данных совместно используют шину, но в архитектурах Гарварда это не означает, что весь код и данные должны сначала проходить через регистры ЦП?

Как вы, наверное, догадываетесь, я слишком смущен всем этим делом. Всегда программируя на более высоком уровне абстракции, я легко беспокоюсь о таких деталях. Любая помощь приветствуется.


2
В простых микроконтроллерах для выполнения не требуется копировать из памяти программ (часто в настоящее время флэш-память) в оперативную память.
Дэвид

Это все потому, что оперативная память быстрее, чем Flash, но, поскольку она теряет данные после потери питания, появляется энергонезависимая память Flash. Когда питание включено, данные загружаются из флэш-памяти в ОЗУ, и процессор начинает работать, все это повторяется.
Лазарь

Ответы:


13

Это зависит от устройства.

ОЗУ может быть построено быстрее, чем Flash; это начинает играть важную роль в диапазоне 100 МГц.

Простые микроконтроллеры

Маленькие медленные микроконтроллеры выполняются прямо из Flash. Эти системы обычно имеют больше Flash, чем SRAM.

Системы среднего уровня

Как только ваше устройство становится быстрее, ситуация несколько иная. Системы среднего уровня ARM также могут делать это, или они могут иметь загрузчик ПЗУ с маской, который делает что-то более умное: возможно, загрузку кода с USB или внешних EEPROM во внутреннюю SRAM.

Большие системы

Большие, более быстрые системы будут иметь внешнюю DRAM и внешнюю Flash. Это типично для архитектуры мобильного телефона. На этом этапе доступно много оперативной памяти, и она работает быстрее, чем Flash, поэтому загрузчик скопирует и выполнит ее. Это может включать в себя передачу данных через регистры ЦП или передачу DMA, если доступен модуль DMA.

Гарвардские архитектуры, как правило, небольшие, поэтому не беспокойтесь о стадии копирования. Я видел ARM с «гибридным гарвардом», который представляет собой единое адресное пространство, содержащее различную память, но две разные единицы выборки. Код и данные могут извлекаться параллельно, если они не из одной и той же памяти. Таким образом, вы можете получить код из Flash и данные из SRAM или код из SRAM и данные из DRAM и т. Д.


1

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

Физическая структура оперативной памяти позволяет нам создавать очень быстрые устройства; намного быстрее, чем вспышка. На этом этапе имеет смысл скопировать блоки кода в оперативную память перед выполнением. Это также приносит дополнительные преимущества разработчику, такие как возможность изменять код во время выполнения.

в архитектурах фон Неймана, где память программ и данных совместно используют шину, но в архитектурах Гарварда это не означает, что весь код и данные должны сначала проходить через регистры ЦП?

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

Например, когда вы ссылаетесь на адрес 0x000f0004 на микроустройстве, вы можете считывать адрес 0x0004 из флэш-памяти. Виртуальный адрес является 0x000f0004, но физический адрес только 0x0004 - весь 0x000fxxxx адресного пространства отображается на устройство 4KB физической памяти. Конечно, это всего лишь пример, и метод управления и организации виртуального адресного пространства сильно отличается в разных архитектурах.

Таким образом, когда вы говорите, что «программа начинает выполнять [...] с адреса 0x0000, который почти всегда является самым низким адресом во флэш-памяти», вы не гарантируете правильность. На самом деле, многие микроконтроллеры начинаются с 0x1000.


3
Я бы сказал, что различие становится актуальным около 20-40 МГц, а не 100 МГц, так как большинство флэш-устройств, которые я видел, начинают требовать состояния ожидания примерно в этот момент. Во многих случаях флэш-код будет включать в себя схемы, так что каждая выборка будет захватывать несколько командных слов, так что для многих видов кода «штраф» за запуск с флэш-памяти будет составлять только около 5-10%, но для некоторых других видов кода. код (например, с большим количеством прыжков) штраф может быть гораздо более серьезным.
суперкат

Это не виртуальная адресация, это сопоставленный с памятью ввод / вывод (область памяти сопоставляется с вводом / выводом с использованием периферийного устройства, имя на многих MCU - «Static Memory Controller»). Конечно, ввод / вывод обращается к другой памяти, поэтому мы иногда не думаем об этом как о вводе / выводе. Но это определенно не виртуальное отображение памяти.
Бен Фойгт

1

То, что вы говорите, не совсем верно или ложно. Для этого есть разные сценарии.

Это зависит от того, программируете ли вы на необработанном оборудовании или на оборудовании, установленном с ОС.

Ваша операционная система, работающая на компьютере общего назначения, получает код с жесткого диска и сохраняет его в оперативной памяти для более быстрого доступа. Если ваш процессор будет пытаться извлекать данные непосредственно с жесткого диска на постоянной основе, то операции будут намного медленнее из-за несоответствия скорости между двумя. Таким образом, ваша оперативная память вступает в игру, где часть вашего повторяющегося кода хранится для быстрого доступа. И это также еще больше доступно в кэш-памяти процессоров, чтобы сделать ее еще быстрее.

Теперь, когда вы работаете с микроконтроллером, все зависит от того, где вы разместите свои данные на чипе. Если данные статичны, вы можете разместить их в памяти кода, что сэкономит вашу оперативную память, которая сравнительно намного меньше памяти кода. На языке Си, когда вы инициализируете тип данных с использованием статического или в каком-либо компиляторе, данные префикса const будут храниться в памяти кода или же будут храниться в ОЗУ. А в сборке вы напрямую используете DB (Определить байт в случае Basic 8051) для инициализации данных в определенном месте. Теперь даже в некоторых контроллерах, таких как PIC ARM, вы можете записывать ПЗУ во время выполнения, но выборка данных займет много времени.

Кроме того, в среднем уровне имеются сложные аппаратные средства загрузчика, которые сообщают контроллерам или процессору, откуда следует запускать код запуска, или он сам по себе является кодом запуска, который фактически сегментирован в памяти, так что существует множество возможностей из-за улучшения Я бы сказал, гибридное продвижение в отрасли, которое смешивает всю концепцию обычных RAM ROM и памяти. Так что в основном твоя путаница верна.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.