Я новичок в программировании встраиваемых систем, начав вчера, и я заметил кое-что, что мне показалось странным. У меня очень простая программа, которая ничего не делает, кроме возврата 0.

int main() {

    return 0;
}

Когда я запускаю это в IAR Embedded Workbench, у меня есть представление памяти, показывающее мне память программ. Я заметил, что в памяти есть некоторая память, но тогда это большой блок пустого пространства, а затем снова есть память (я отстой при объяснении: P, так что вот изображение памяти)

enter image description here

Пожалуйста, помогите мне понять это немного больше, чем я понимаю сейчас. Я действительно не знаю, что искать, потому что я новичок в этом.

1
Arbitur 5 Май 2014 в 01:45

3 ответа

Лучший ответ

Первые две строки - это 8 векторов прерываний, представленных в виде 32-битных инструкций с последним старшим байтом. То есть считайте их группами по 4 байта, начиная с последнего байта, а затем преобразуйте их в инструкцию обычным способом. Первые несколько векторов, включая сброс в ячейку памяти 0, оказываются инструкциями LDR, которые загружают немедленный адрес в регистр ПК. Это заставляет процессор переходить к этому адресу. (Вектор сброса также является первой инструкцией, выполняемой при включении устройства.)

Вы можете увидеть структуру инструкции LDR здесь , или во многих других местах через поиск в Интернете. Если мы запишем вектор сброса 18 f0 95 e5 как e5 95 f0 18, то мы увидим, что в регистр ПК загружен адрес, расположенный со смещением 0x20.

Таким образом, следующие две строки - это ячейки памяти, на которые ссылаются инструкции в первых двух строках. Вектор сброса отправляет ПК на 0x00000080, где запускается среда выполнения C вашей программы. (Другие векторы отправляют ПК на 0x00000170 ближе к концу вашей программы. Какая эта инструкция остается на усмотрение читателя.)

Обычно среда выполнения C - это код, добавляемый в начало вашей программы, который загружает глобальные переменные в RAM из флэш-памяти и устанавливает для неинициализированного RAM значение 0. После этого запускается ваша программа.

Ваш первоначальный вопрос был: почему такой большой промежуток неиспользованной вспышки? Ответ заключается в том, что флеш-память на самом деле не является чем-то особенным, поэтому мы можем немного потратить впустую, и что наличие там дополнительного места обеспечивает прямую совместимость. Если нам нужно увеличить размер таблицы векторов, нам не нужно перемещать код. Фактически, эта модель прерывания была изменена в новых процессорах ARM Cortex.

2
uncleO 5 Май 2014 в 00:19

UncleO прав, но вот дополнительная информация.

Командный файл компоновщика проекта (* .icf для IAR EW) определяет расположение разделов в памяти. (Посмотрите в Project-> Options-> Linker-> Config, чтобы определить файл конфигурации компоновщика.) Если вы просматриваете командный файл компоновщика с помощью текстового редактора, вы можете определить, где находится раздел с именем .intvec (или аналогичный) по адресу 0x00000000. И затем он может найти другой раздел (возможно .text) по адресу 0x00000080.

Вы также можете увидеть эти разделы памяти, указанные в файле .map, вместе с их расположением. (Убедитесь, что в Project-> Options-> Linker-> List установлен флажок «Generate linker map file»). Однако файл карты является выходом сборки, и это командный файл компоновщика, который определяет местоположения.

Таким образом, это пространство в памяти есть, потому что командный файл компоновщика указал, что это так. Я не уверен, нужно ли это пространство, но это определенно не проблема. Возможно, вы сможете поэкспериментировать с командным файлом компоновщика и переместить второй раздел. Но таблица исключений (также известная как таблица векторов прерываний) должна располагаться по адресу 0x00000000. И вы захотите убедиться, что вектор сброса указывает на новое местоположение кода запуска, если вы его переместите.

1
kkrambo 5 Май 2014 в 12:54

Адреса физической (не виртуальной) памяти отображаются на физические схемы. Самые низкие адреса часто отображаются в регистры, а не в массивы RAM. В интересах согласованности данный адрес обычно соответствует одной и той же функциональности на разных процессорах одного и того же семейства, а отсутствующая функциональность отображается как небольшая дыра в сопоставлении адресов.

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

В качестве альтернативы, как предлагает @Martin, он может представлять неинициализированную и доступную только для чтения флэш-память в виде байтов --. В отличие от действительно неназначенных адресов, доступ к ним вряд ли вызовет исключение, и вы даже можете заставить их «снова появиться» с помощью соответствующих команд контроллера Flash.

На современной машине класса настольных компьютеров виртуальная память скрывает все это от вас, и даже части физической карты адресов могут быть настроены. Многие процессоры встроенного класса позволяют конфигурировать вплоть до определения местоположения таблицы векторов прерываний.

0
Potatoswatter 4 Май 2014 в 22:24