Программирование DSP Blackfin: утилита elfloader.exe Tue, April 16 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Blackfin: утилита elfloader.exe Печать
Добавил(а) microsin   

В этой статье приведен перевод частей документации [1], касающихся только процессоров Blackfin ADSP-BF53x. Описывается использования утилиты для генерации файла загрузки - elfloader.exe.

[Введение: основные понятия и термины]

Этот документ описывает главным образом функционал утилиты загрузки, а также процесс loading-а (загрузка) и splitting-а (разделение исполняемого кода). Некоторые непонятные сокращения и термины см. в разделе "Словарик" статей [3, 4]. 

Загрузчик и Утилита загрузки. Под термином утилита загрузки подразумевается программа elfloader.exe (Loader Utility), которая является частью пакета разработки VisualDSP++. Утилита загрузки выполняет завершающую обработку процесса компиляции, получая на входе один или несколько исполняемых файлов (с расширением *.dxe) и генерируя на выходе файл загрузки (с расширением *.ldr). В процессе обработки файлов *.dxe утилита загрузки распаковывает сегменты, декларированные командой TYPE(RAM) в файле Linker Description File (.ldf). Поскольку файл .dxe следует стандарту Executable and Linkable Format (ELF), утилита загрузки часто называют утилитой elfloader. См. также раздел "Как работает утилита загрузки".

Splitter Utility. Splitter utility также является частью пакета VisualDSP++. Утилита сплиттера обрабатывает один или несколько файлов исполняемых файлов (с расширением .dxe), распаковывает сегменты, декларированные командой TYPE(ROM) файла Linker Description File (.ldf), и генерирует файл, состоящий из инструкций (команд) процессора. Это файл прошивается в память EPROM или flash процессора, которая подключена к нему через системную шину, так что процессор может напрямую выбирать оттуда команды и выполнять их. Подробнее про работу Splitter Utility см. раздел "Splitter Utility Operations" руководства [1].

Работа утилиты сплиттера и утилиты загрузки может быть обработана либо отдельными утилитами, либо одной и той же программой (см. раздел "Не загружаемые файлы (Non-bootable) и загружаемые (Boot-loadable) - в чем разница?"). Для загружаемых файлов выходной файл содержит как инструкции кода, так и специальные данные потоков загрузки (заголовки, описывающие секции файла загрузки, см. [2]).

Примечание: splitter utility не имеет отношения к процессорам Blackfin, и в этом переводе документации [1] не рассматривается.

Файл загрузки. Файл загрузки (loader file) генерируется утилитой загрузки. Обычно этот файл имеет расширение .ldr, и поэтому часто называется файлом LDR. Файлы загрузки могут удовлетворять одному или нескольким форматам. Общие форматы содержимого файла загрузки: Intel hex-32, binary или ASCII (чаще всего применяется двоичный формат, binary). Независимо от формата файл загрузки описывает образ загрузки (boot image), который можно увидеть в двоичной (binary) версии файла загрузки. Также см. раздел "Не загружаемые файлы (Non-bootable) и загружаемые (Boot-loadable) - в чем разница?".

Опции командной строки утилиты загрузки. Поведение утилиты загрузки управляется многочисленными опциями командной строки, которые будут подробно рассмотрены далее (в этом переводе [1] только для процессора Blackfin). От опций зависит генерация выходного файла загрузки *.ldr.

Раздел "Load" свойств проекта. В среде VisualDSP++ можно управлять свойствами проекта (Project Options). Диалог редактирования свойств проекта имеют раздел свойств загрузки (Load). Этот графический интерфейс помогает сформировать командную строку для утилиты загрузки (утилита elfloader.exe автоматически будет запущена средой VisualDSP, если выбрана генерация файла загрузки через Project Options -> Project -> раздел опций Target -> Type: Loader file).

Режим загрузки (Boot Mode). Большинство процессоров поддерживают несколько режимов загрузки. Режим загрузки определяет специальные входные выводы процессора, которые опрашиваются им либо после сброса (reset), либо после выхода из состояния выключения (power-down state). Подробнее про режимы загрузки см. раздел "Boot Modes", а также статью [2].

Boot Strapping. Процесс загрузки состоит из нескольких шагов, таких как предварительная загрузка ядра (boot kernel) или управление загрузчиками второго уровня (second-stage loaders). Эта процедура называется boot strapping или boot ROM.

Код инициализации (Init Code). Это часть потока загрузки процессоров Blackfin, и её можно рассматривать как специальный блок загрузки. В то время как обычно сначала загружаются все загружаемые блоки приложения, и затем управление передается в само приложение, код инициализации выполняется во время загрузки - как первый шаг всего процесса загрузки. Такое происходит, когда код инициализации загружается и выполняется перед любым другим загружаемым блоком. Необходимость наличия кода инициализации обусловлена такими случаями, как необходимость инициализации памяти SDRAM (например, код приложения и данные должны быть загружены в SDARM), настройка каких-то специфичных аппаратных средств системы, обеспечения процедуры обновления, или для оптимизации процесса загрузки основного приложения.

Global Header. Некоторые загрузчики ядра (boot kernel) ожидают наличия в потоке загрузки специальной информации. Этот тег называется глобальным заголовком (global header).

Callback Routine. Некоторые процессоры опционально могут вызывать подпрограмму, определенную пользователем - после того как блок загрузки загружен и обработан. Эта подпрограмма называется callback routine (процедура обратного вызова). Она может предоставить такие функции, как реализация контрольной суммы кода, стратегии декомпрессии.

Slave Boot, Master Boot. Термин Slave Boot относится ко всем режимам загрузки, когда целевой процессор работает как подчиненное устройство. Master Boot - когда при загрузки внешнее хранилище образа загрузки обрабатывается самим процессором (т. е. хранилище работает как подчиненное устройство). Подробнее см. [2].

Менеджер загрузки (Boot Manager). Менеджер загрузки - код firmware, который определяет, какое приложение должно быть загружено. Приложение обычно представлено как проект среды VisualDSP++, и результат компиляции проекта сохраняется в исполняемом файле с расширением *.dxe. Сам по себе менеджер загрузки может быть реализован как в файле основного приложения *.dxe, так и в виде отдельного файла *.dxe. Часто менеджер загрузки выполняется в так называемом коде инициализации (Init Code).

В сценариях загрузки slave boot управление загрузкой возлагается на процессор хоста, и это не требует специальной поддержки со стороны VisualDSP++.

Multi-.dxe Boot. Файл загрузки может содержать в себе данные файлов нескольких приложений (*.dxe), если утилита elfloader была запущена с указанием нескольких входных файлов *.dxe. Либо менеджер загрузки должен решить, какое именно приложение из нескольких должно быть загружено и запущено, либо альтернативно одно загруженное приложение может остановить свою работу, после чего загрузится следующее приложение. В некоторых случаях одно приложение может также состоять из нескольких файлов *.dxe (чаще всего из DXE для Init Code и DXE для основного приложения).

Next .dxe File Pointer. Если файл загрузки состоит из нескольких приложений, некоторые форматы потока загрузки позволяют организовать файл загрузки в виде связанного списка. Указатель на следующий DXE (next .dxe pointer, NDP) - просто указатель на место, где в потоке загрузки находится следующее приложение.

Preboot Routine. Подпрограмма, выполняющаяся перед загрузкой (preboot routine), представлена в частях кода boot ROM процессора (однократно программируемая, OTP память, которая записана на заводе). Preboot читает память OTP, и настраивает некоторые регистры MMR на основе заводских инструкций и инструкций пользователя, как это запрограммировано в память OTP. Preboot routine запускается до загрузки ядра (boot kernel).

[Что такое Loading, Splitting]

После завершения цикла отладки, аппаратура процессора должна быть запущена отдельно, в составе рабочей системы (без подключенного отладчика). После включения питания нужно инициализировать встроенные в чип процессора, и находящиеся вне чипа устройства памяти. процесс инициализации областей памяти часто называют загрузкой (booting). Таким образом выходной файл линкера должен быть преобразован в формат, который может быть прочитан загрузчиком процессора (кодом Boot ROM). Этот процесс преобразования обрабатывается утилитой загрузчика и/или сплиттера. Утилита loader/splitter использует отлаженные и протестированные на этапе разработки исполняемые файлы (*.dxe), как и общую память и файлы оверлея в качестве входных данных, и генерирует читаемый процессором файл.

В пакете разработки VisualDSP++ 5.0 включены следующие утилиты loader и splitter:

elfloader.exe (утилита загрузки, loader utility) для семейств процессоров Blackfin, TigerSHARC и SHARC. Утилита загрузки для процессоров Blackfin работает также и как утилита ROM splitter, когда запускается с соответствующими опциями командной строки.

elfspl21k.exe (утилита ROM splitter) для семейств процессоров TigerSHARC и SHARC.

На выходе утилит loader/splitter получается либо загружаемый (boot-loadable), либо не загружаемый (non-bootable) файл. Под выходом понимаются данные (обычно это файл с расширением *.ldr), прошиваемые в память целевой системы (это может быть, например, FLASH-память на кристалле ADSP-BF538, или память SPI, откуда загружается программа при включении питания). Есть несколько способов использования выхода утилит загрузки/сплиттера:

Плагин Flash Programmer. Он позволяет записать файл загрузки в область PROM процессора платы разработчика EZ-KIT Lite®. Подробнее см. справочную систему VisualDSP++, раздел Flash Programmer.

Симулятор загрузки. Можно использовать VisualDSP++ для симулирования загрузки в сессии симулятора (в настоящее время поддерживается для процессоров ADSP-21060, ADSP-21061, ADSP-21065L, ADSP-21160 и ADSP-21161). Загрузите файл загрузки, и затем сбросьте процессор, чтобы отладить подпрограммы загрузки. Не требуется никакой аппаратуры: просто укажите на место положения файла загрузки, и позвольте симулятору выполнить остальную работу. Вы можете по шагам выполнит код boot kernel и посмотреть, как он переносит в память остальной код.

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

[Не загружаемые файлы (Non-bootable) и загружаемые (Boot-loadable) - в чем разница?]

Не загружаемый файл выполняется напрямую из внешней памяти процессора (обычно FLASH), в то время как данные загружаемого файла транспортируются во внутреннюю (и/или иногда во внешнюю память SDRAM), и после этого запускается на выполнение. Загружаемый файл записывается в устройство внешней памяти (это может быть SPI EPROM, или FLASH) Вашей целевой системы. Утилита загрузки выводит загружаемые файлы в форматах, которые понимают большинство прошивальщиков EPROM (такие форматы, как Intel hex-32 и Motorola S). Для особых случаев поддерживаются другие форматы файла и режимы загрузки, часто используется сырой, двоичный формат (подробнее см. "File Formats" [1]).

Не загружаемые образы выполняются из внешней памяти процессора, с пропуском механизмов загрузки. Подготовка не загружаемого образа EPROM называется сплиттингом (splitting). В большинстве случаев (за исключением процессоров Blackfin) разработчики, использующие процессоры с плавающей точкой или фиксированной точкой, используют splitter вместо утилиты loader, чтобы сгенерировать не загружаемый образ памяти.

Как загружается процессор и дизайн программы диктуют метод, каким будет вызвана утилита loader/splitter, чтобы обработать и преобразовать исполняемые файлы:

• Для процессоров Blackfin операции loader и splitter обрабатываются одной утилитой, elfloader.exe. Функция splitter вовлекается другим набором опций командной строки, отличающимся от опций функции loader. В VisualDSP++ 5.0, в дополнение к опции -readall, утилита loader для процессоров ADSP-BF51x, BF52x, BF54x Blackfin может автоматически вызывать программу сплиттера. Для дополнительной информации см. в [1] описание опции -readall.

• Для процессоров TigerSHARC и SHARC операции splitter обрабатываются отдельной утилитой сплиттера elfspl21k.exe.

Примечание: везде в тексте, где встречается наименование процессора без префикса BF51x, BF52x, BF53x, BF561 и т. п., подразумевается процессор Blackfin с префиксом ADSP- (ADSP-BF51x, ADSP-BF52x, ADSP-BF53x, ADSP-BF561 и т. п.).

[Как работает утилита загрузки]

Общие задачи, которые выполняет утилита загрузки, могут включать следующее:

• Обработка опций loader в командной строке.
• Форматирование выходного файла .ldr в соответствии с указаниями пользователя. Поддерживается несколько форматов файла: binary, ASCII, Intel hex-32 и некоторые другие, подробнее см. раздел "File Formats" [1].
• Упаковка данных кода в под отдельные форматы данных, зависящие от процессора и подключенной микросхемы памяти: 8-битный, 16-битный или для некоторых процессоров 32-битный.
• Добавление кода и данных из указанного файла исполняемого кода (Init Code DXE), если это необходимо.
• Добавление boot kernel поверх кода пользователя.
• Если указано, предварительное программирование размещения файла .ldr в указанное место PROM.
• Указание идентификаторов процессора для нескольких файлов .dxe для много процессорной системы, если это необходимо.

Вы можете запустить утилиту loader неявно, когда запускаете компиляцию проекта из среды разработки VisualDSP++ (когда задано генерировать файл загрузки через Project Options -> Project -> раздел опций Target -> Type: Loader file), или из командной строки. Чтобы настроить поведение утилиты при запуске из VisualDSP++, откройте свойства проекта Project Options в меню Project, и в диалоге настройки свойств проекта поменяйте Target из типа Executable file в Loader File, и затем отредактируйте раздел Load свойств проекта.

Работа утилиты загрузки elfloader.exe зависит от свойств загрузки (раздел Load свойств проекта), которые управляют тем, как утилита загрузки преобразует исполняемые файлы в загружаемые файлы, позволяя Вам выбрать такие возможности, как ядра (kernels), режимы загрузки (boot modes) и выходные форматы файла (output file formats). Эти опции настраиваются в разделе Load свойств проекта Project Options VisualDSP++, или их можно задать из командной строки. Опции страниц раздела Load соответствуют опциям командной строки утилиты elfloader.exe.

[Режимы загрузки (Boot Modes)]

Как только исполняемый файл полностью отлажен, утилита загрузки готова к преобразованию исполняемого файла (или нескольких исполняемых файлов) в загружаемый процессором (processor-loadable, или boot-loadable) файл. Загружаемый файл может быть автоматически загружен (booted) в процессор при включении питания (power-up) или программного сброса системы (software reset). Способ, каким утилита будет создавать загружаемый файл, зависит от того, как загружаемый файл загружается в процессор (и конечно же, это задается пользователем в разделе Load свойств проекта или через опции командной строки утилиты elfloader.exe).

Режим загрузки (boot mode) процессора [2] определяется опросом одного или большего количества специальных внешних выводов корпуса процессора (например, для процессора Blackfin ADSP-BF538 это выводы BMODE1, BMODE0). Последовательности загрузки, жестко зависящие также от модели процессора, подробно описаны в следующих разделах.

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

• No-Boot Mode
• PROM Boot Mode
• Host Boot Mode

No-Boot Mode. После сброса процессора начинает напрямую вычитывать и выполнять инструкции из устройств EPROM/flash (у процессора ADSP-BF538F эта память может быть даже встроена в кристалл чипа процессора). Эта схема не требует никаких механизмов загрузки (т. е. код Boot ROM не задействован). На программу пользователя возлагается инициализация работоспособности и содержимого энергозависимой памяти (SRAM L1, SDRAM).

Утилита сплиттера генерирует файл, который может быть прошит в память PROM.

PROM Boot Mode. После сброса процессор начинает вычитывать данные из параллельного или последовательного устройства памяти PROM. Память PROM хранит специальным образом отформатированный поток загрузки (заточенный под обработку кодом Boot ROM, см. [2]), а не просто код инструкций. Вместе с данными приложения поток загрузки содержит дополнительную информацию, такую как адреса назначения и счетчики слов. Маленькая программа, так называемый загрузчик ядра (или же Boot ROM, как у процессоров Blackfin) анализирует поток загрузки и в соответствии с ним инициализирует области памяти процессора. Загрузчик ядра (или код Boot ROM) работает под управлением целевого процессора. В зависимости от архитектуры, загрузчик ядра может выполняться либо из встроенной в чип памяти boot RAM, или из устройства памяти PROM, копируя код в SRAM процессора и выполняя его оттуда.

Утилита загрузки генерирует данные потока загрузки из выходных данных линкера (один или несколько исполняемых файлов *.dxe) и сохраняет поток загрузки в файл (обычно это файл *.ldr) в формате, подходящем для прошивки в PROM.

Host Boot Mode. В этой схеме целевой процессор ведет себя как подчиненное устройство, управляемое системой хоста [2]. После сброса процессор задерживает выполнение программы, пока не получит сигнал от хост-системы, что процесс загрузки завершен. В зависимости от возможностей аппаратуры, есть два разных метода загрузки под управлением хоста. Первый метод - когда система хоста получает полное управление над всеми областями памяти целевой подчиненной системы. Хост приостанавливает работу целевой системы, пока инициализирует все области памяти. По второму методу хост обменивается с целевой системой специальными сигналами (см. [2]), и последовательно передает данные подчиненному целевому процессору, на котором работает загрузчик ядра (или код Boot ROM). Код загрузчика может быть выполнен из встроенного в чип Boot ROM, или может быть загружен от хоста в SRAM по любой из других допустимых схем загрузки.

Утилита loader/splitter генерирует файл, который использует система хоста. Он зависит от возможностей устройства хоста и от архитектуры целевой системы - ожидает ли хост сырые данные приложения, или же отформатированный поток загрузки.

В этом контексте загружаемый файл отличается от не загружаемого тем, что загружаемый файл кроме кода приложения содержит дополнительные данные, которые должен обработать загрузчик ядра (код Boot ROM). Не загружаемый файл содержит только чистый исполняемый код инструкций (команд) процессора.

[Загрузка процессора ADSP-BF53x/BF561]

При включении питания и/или после сброса процессор переходит в последовательность boot mode, который конфигурируется внешними входными выводами BMODE (см. [2]). Это специальные, выделенные выводы корпуса процессора, которые не обслуживают никаких других функций. Состояние выводов BMODE может быть программно прочитано через биты регистра конфигурации системы после сброса (System Reset Configuration Register, SYSCR).

Процессоры Blackfin моделей ADSP-BF53x или ADSP-BF561 могут загружаться либо из 8-битной, либо из 16-битной памяти flash/PROM, или из адресуемой 8 битами, 16 битами или 24-битами памяти SPI. Процессоры ADSP-BF561 не поддерживают загрузку через 24-битно адресуемую память SPI. Также имеются опции no-boot (bypass mode, пропуск запуска кода Boot ROM), когда выполнение программы сразу начинается из 16-разрядной внешней памяти.

Опции загрузки также могут зависеть и от ревизии кристалла. Подробнее про варианты загрузки Blackfin см. [2].

После сброса процессор ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 передает управление во встроенный в кристалл код Boot ROM (если BMODEx != 00), или в область внешней 16-разрядной памяти (если BMODEx == 00) по адресу 0x20000000. Подробнее про Boot ROM процессора см. раздел "ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 On-Chip Boot ROM".

В таблице 3-1 сведены режимы загрузки и стартовые адреса процессоров ADSP-BF531, ADSP-BF532, ADSP-BF533, ADSP-BF538 и ADSP-BF539.

Откуда происходит загрузка
BMODE[1:0]
Адрес начала
выполнения кода

ADSP-BF531
ADSP-BF532
ADSP-BF533
ADSP-BF538
ADSP-BF539
Выполнение из внешней 16-битной памяти, подключенной к ASYNC Bank0 (пропуск запуска кода Boot ROM). 00 0x20000000
Загрузка из 8/16 битной параллельной микросхемы FLASH/PROM. 01 0xFFA08000 0xFFA00000
Загрузка через SPI в режиме SPI Slave mode (данные поступают от хоста SPI). 10
Загрузка из памяти SPI, адресуемой 8/16/24 битами, с поддержкой микросхем памяти Atmel AT45DB041B, AT45DB081B и AT45DB161B DataFlash® (хостом SPI выступает загружаемый процессор Blackfin). 11

• Выполнение из 16-разрядной внешней памяти – процессор начинает выполнение кода с адреса 0x20000000 (код с 16-разрядной упаковкой). В этом режиме передача управления в Boot ROM пропускается. Все конфигурационные настройки внешней шины сбрасываются в состояние, рассчитанное на самое медленное внешнее устройство памяти: 3 цикла время удержания (hold time), 15 циклов для доступа на чтение/запись, 4 цикла на предустановку (setup).

• Загрузка из 8- или 16-разрядной внешней flash-памяти – в этом режиме подпрограмма загрузки расположена в области Boot ROM, и для потока загрузки используется асинхронный банк памяти 0. Все настройки конфигурации сбрасываются в расчете на самое медленное устройство памяти: 3 цикла время удержания (hold time), 15 циклов для доступа на чтение/запись, 4 цикла на предустановку (setup). Boot ROM анализирует первый байт потока загрузки по адресу 0x20000000. Если он равен 0x40, то выполняется 8-битная загрузка. Если байт равен 0x60, то подразумевается 16-разрядное устройство памяти и выполняется 8-разрядный DMA. Байт 0x20 также подразумевает 16-разрядную память, но выполняет 16-разрядный DMA.

• Загрузка через SPI под управлением хоста – процессор Blackfin работает как подчиненное устройство SPI, и конфигурируется для приема байтов файла .ldr от хоста (мастера) шины SPI. Описание процедуры обмена и используемых сигналов см. в [2].

• Загрузка из последовательной памяти SPI (EEPROM или flash) – используются микросхемы памяти с 8-, 16- или 24-разрядной адресацией, также поддерживаются микросхемы AT45DB041, AT45DB081, AT45DB161, AT45DB321, AT45DB642 и AT45DB1282 DataFlash® от компании Atmel. Описание процедуры детектирования типа микросхемы и сигналов обмена см. в [2].

Процессоры ADSP-BF534, BF536, BF537 также поддерживают загрузку через интерфейсы TWI и UART, подробнее см. [1].

Благодаря наличию механизма Multi-.dxe Boot программист может создать собственный загрузчик кода, который позволит загрузить (или даже обновить) приложение из любых других источников или через любой другой доступный интерфейс связи с внешним миром.

[ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 On-Chip Boot ROM]

После того, как встроенный в процессор код загрузки (On-Chip Boot ROM) получает управление, то он выполняет следующие действия:

1. Настраивает режим супервизора (supervisor mode) путем выхода из обработчика прерывания RESET, и перехода в прерывание с самым низким приоритетом (IVG15).

Обратите внимание, что on-chip boot ROM процессоров ADSP-BF534, BF536 и BF537 выполняется на уровне приоритета Reset, не снижая уровень приоритета выполнения на самый низкий уровень приоритета прерываний.

2. Проверяет, был ли RESET программным сбросом, и если это так, то либо пропускает всю последовательность загрузки и делает переход на начало памяти L1 (адрес 0xFFA00000 для процессоров ADSP-BF533, BF534, BF536, BF537, BF538 и BF539 processors; адрес 0xFFA08000 для процессоров ADSP-BF531, BF532). Проверка делается кодом Boot ROM путем анализа бита NOBOOT (бит 4) регистра конфигурации системы после сброса (System Reset Configuration Register, SYSCR). Если бит 4 не установлен, то код Boot ROM выполняет полную процедуру загрузки. Если бит 4 установлен, то код Boot ROM пропускает полную последовательность загрузки и сразу передает управление в начало памяти L1.

3. Бит NOBOOT (бит 4 регистра SYSCR) не установлен, начинается полная последовательность загрузки (см. рис. 3-1).

ADSP Blackfin booting sequence fig31

Рис. 3-1. Последовательность загрузки процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539.

Последовательность загрузки процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 отличается от процессоров ADSP-BF535. On-chip boot ROM для этих процессоров ведет себя так же, как и загрузчик второй стадии процессора ADSP-BF535 (подробнее см. раздел "ADSP-BF535 Processor On-Chip Boot ROM"). У кода Boot ROM есть возможность обрабатывать адреса и количество байт для каждого загружаемого блока потока загрузки. Это смягчает требования к условиям работы загрузчика второго уровня, потому что полное приложение может быть загружено из различных устройств памяти, когда на самом процессоре есть только встроенный код Boot ROM.

Как уже упоминалось, утилита загрузки преобразует исполняемое приложение (файл .dxe) в загружаемый файл, анализируя код и создавая файл, который состоит из различных блоков. Каждый блок снабжен 10-байтным заголовком, как это показано на рис. 3-1, и более подробно разъяснено в последующих секциях (также см. [2]). Заголовки, в свою очередь, читаются и обрабатываются кодом Boot ROM во время загрузки.

10-байтный заголовок предоставляет загрузчику (код Boot ROM) всю необходимую информацию — куда надо поместить блок, сколько байт занимает блок, и что нужно делать с этим блоком.

[Потоки загрузки ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539]

Далее описаны поток загрузки, заголовки и флаги для процессоров ADSP-BF531, ADSP-BF532, ADSP-BF533, ADSP-BF534, ADSP-BF536, ADSP-BF537, ADSP-BF538 и ADSP-BF539.

Когда утилита загрузки преобразует код из входного файла .dxe в блоки, помещаемые в выходной файл загрузки, каждый блок получает 10-байтный заголовок (показанный на рис. 3-2), за которым идет тело блока (если это не zero-блок) или тело no-block (если это zero-блок). Описание структуры заголовка приведено в таблице 3-3.

ADSP Blackfin boot stream structure fig32

Рис. 3-2. Процессоры ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539: структура потока загрузки.

Таблица 3-3. Структура заголовка блока ADSP-BF531, BF532, BF533.

Поле Описание
ADDRESS 4-байтовый адрес, указывающий на место расположение блока в памяти (куда блок должен быть загружен).
COUNT 4-байтовое количество байт загружаемого блока.
FLAG 2-байтовое поле, в котором содержатся флаги.

На рис. 3-3 и в таблице 3-4 поясняется структура битов флагов.

ADSP Blackfin FLAG field fig33

Рис. 3-3. Биты флагов для 2-байтового поля флагов заголовка.

Таблица 3-4. Структура флагов.

Поле Описание
Zero-fill block Показывает, что загружаемый блок является буфером в памяти, который должен быть просто заполнен нулями. Тело этого блока не присутствует в файле загрузки (есть только заголовок). Когда утилита загрузки обрабатывает файл *.dxe и обнаруживает большие буферы с нулями, то она создает такой блок, чтобы уменьшить размер файла загрузки и следовательно время загрузки. Если этот бит установлен, то после заголовка не будет тела блока с данными.
Processor type Показывает тип процессора - либо ADSP-BF531, BF532, BF538, либо ADSP-BF533, BF534, BF536, BF537, BF539. После завершения загрузки код Boot ROM будет передавать управления по адресу, который зависит от этого бита (см. таблицу 3-1). Если этот бит равен 1, то это означает процессор BF533, BF534, BF536, BF537, BF538, BF539, если 0, то процессор BF531, BF532.
Initialization block Показывает, что этот блок должен быть выполнен в начале загрузки (блок соответствует Init Code DXE). Флаг индикатора позволяет коду Boot ROM выполнить некоторое количество инструкций до загрузки кода действующего приложения. Когда код Boot ROM детектировал наличие блока инициализации, он загружает этот блок во внутреннюю память процессора, и выполняет инструкцию CALL, передающую управление в этот блок как в процедуру (соответственно Init Code должен быть скомпилирован как процедура, оканчивающаяся на инструкцию RTS). Функция кода инициализации позволяет пользователю запустить специальный код, который может подготовить среду загрузки для кода основного приложения (такое часто требуется, если в системе нужно предварительно сконфигурировать SDRAM). На рис. 3-4 и 3-5 показан этот процесс. Код инициализации может быть добавлен в файл загрузки *.ldr с использованием опции -init командной строки утилиты загрузки. См. ниже врезку "Блоки инициализации ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539".
Ignore block Показывает, что этот блок не должен загружаться в память. Этот блок будет пропущен, и загрузка перейдет к следующему блоку. В настоящее время это не реализовано для кода приложения.

Этот флаг эквивалентен флагу FIRST в потоках загрузки процессоров ADSP-BF51x, BF52x, BF54x. Из-за того, что флаг IGNORE используется для других целей на ADSP-BF51x, BF52x, BF54x, флаг FIRST изобретен, чтобы показать первый заголовок.
Compressed block Показывает, что блок содержит сжатые данные (сжатый блок). Сжатый блок может включать в себя некоторое количество сжатых совместно блоков, чтобы сформировать один сжатый блок.
Last block Показывает, что это последний блок, загружаемый в память. После загрузки последнего блока процессор передает управление в начало памяти L1, что приведет к запуску приложения. Когда делается переход в память L1 для выполнения кода приложения, процессор все еще находится в режиме супервизора с самым низким уровнем приоритета (IVG15).

Обратите внимание, что процессоры ADSP-BF534, BF536, BF537 могут иметь специальный последний блок, если режим загрузки TWI (Two Wire Interface, I2C, двухпроводный интерфейс). Утилита загрузки сохраняет все данные от 0xFF903F00 до 0xFF903FFF и делает последний блок с этими данными. Утилита загрузки, однако, создает обычный последний блок, если в этом диапазоне нет данных. Область 0xFF903F00 .. 0xFF903FFF сохраняется для Boot ROM, чтобы использовать эту память как буфер данных для процесса загрузки.

Опция -init filename дает указание утилите загрузки генерировать блоки, полученные из кода инициализации (Init Code), код берется из файла filename. Блоки кода инициализации помещаются в начало файла загрузки. Они выполняются до того, как остальная часть кода в файле загрузки будет загружена в память и выполнена (см. рис. 3-4).

ADSP Blackfin execution Init Code fig34

Рис. 3-4. Выполнение блока инициализации (Init Code) процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539.

После выполнения кода из блоков инициализации, процесс загрузки продолжит загружать остальные блоки данных, пока не дойдет до последнего блока (см. рис. 3-5). Пример кода инициализации показан в листинге 3-1.

ADSP Blackfin booting application code fig35

Рис. 3-5. Загрузка кода приложения процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539.

Листинг 3-1. Пример блока кода инициализации.

/* Этот файл содержит 3 секции: */
/* 1) Pre-Init Section – эта секция сохраняет в стек все регистры процессора.
   2) Init Code Section – эта секция содержит код инициализации, который
      может быть модифицирован пользователем. В качестве примера здесь
      приведен код инициализации SDRAM (обычная задача для Init Code).
      Настраивается контроллер SDRAM, как это требуется для основных типов
      SDRAM. Разные типы SDRAM могут потребовать другой процедуры инициализации
      (обычно просто других значений, записанных в регистры).
   3) Post-Init Section – эта секция восстанавливает все регистры из стека.
      Пользователь не должен менять секции Pre-Init и Post-Init. Секция
      Init Code может быть модифицирована в соответствии с задачами
      отдельного приложения. */
#include < defBF532.h >
.SECTION program;
/**********************Pre-Init Section************************/
   [--SP] = ASTAT;   /* Stack Pointer (SP) устанавливается на конец */
   [--SP] = RETS;    /* памяти scratchpad (0xFFB00FFC) */
   [--SP] = (r7:0);  /* кодом on-chip Boot ROM */
   [--SP] = (p5:0);
   [--SP] = I0;[--SP] = I1;[--SP] = I2;[--SP] = I3;
   [--SP] = B0;[--SP] = B1;[--SP] = B2;[--SP] = B3;
   [--SP] = M0;[--SP] = M1;[--SP] = M2;[--SP] = M3;
   [--SP] = L0;[--SP] = L1;[--SP] = L2;[--SP] = L3;
/*******************Init Code Section**************************/
/*****Пожалуйста, вставьте код инициализации в эту секцию******/
/*********************Настройка SDRAM**************************/
Setup_SDRAM:
   P0.L = LO(EBIU_SDRRC);
   /* SDRAM Refresh Rate Control Register */
   P0.H = HI(EBIU_SDRRC);
   R0 = 0x074A(Z);
   W[P0] = R0;
   SSYNC;
   
   P0.L = LO(EBIU_SDBCTL);
   /* SDRAM Memory Bank Control Register */
   P0.H = HI(EBIU_SDBCTL);
   R0 = 0x0001(Z);
   W[P0] = R0;
   SSYNC;
   
   P0.L = LO(EBIU_SDGCTL);
   /* SDRAM Memory Global Control Register */
   P0.H = HI(EBIU_SDGCTL);
   R0.L = 0x998D;
   R0.H = 0x0091;
   [P0] = R0;
   SSYNC;
/*********************Post-Init Section************************/
   L3 = [SP++]; L2 = [SP++]; L1 = [SP++]; L0 = [SP++];
   M3 = [SP++]; M2 = [SP++]; M1 = [SP++]; M0 = [SP++];
   B3 = [SP++]; B2 = [SP++]; B1 = [SP++]; B0 = [SP++];
   I3 = [SP++]; I2 = [SP++]; I1 = [SP++]; I0 = [SP++];
   (p5:0) = [SP++];
   (r7:0) = [SP++];
   RETS = [SP++];
   ASTAT = [SP++];
/************************************************************/
   RTS;

Потоки загрузки процессора ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 аналогичны потоку загрузки, используемому загрузчиком ядра второго уровня процессора ADSP-BF535 (подробнее см. раздел "Файлы загрузки, используемые с загрузчиком второго уровня"). Однако, поскольку предыдущие процессоры не реализовали загрузчик второго уровня, их поток загрузки не включает в себя код второй стадии загрузки и связанный с ним 4-байтный заголовок, расположенный поверх кода ядра (kernel code). Здесь также нет 4-байтного глобального заголовка (global header).

Аппаратная установка BMODE = 00 для процессоров ADSP-BF531, BF532 и BF533 или BMODE = 000 для процессоров ADSP-BF535 выберет опцию загрузки no-boot. В этом режиме после сброса выполнение кода загрузки, встроенного в процессор, пропускается, и процессор начинает выборку и выполнение инструкций по адресу 0x20000000 (эта память находится в асинхронном банке памяти 0). Процессор подразумевает наличие памяти с шиной 16 бит, где находятся допустимые для выполнения инструкции кода (т. е. по этому адресу должен находиться чистый код, без служебных заголовков загрузки).

Чтобы создать корректный файл .ldr, который может быть записан либо в параллельную память flash, либо в параллельную память EPROM, Вы должны модифицировать стандартный файл LDF, чтобы в нем был правильно настроен вектор сброса. Фрагменты следующего кода (листинг 3-6 и листинг 3-7) иллюстрируют требуемые модификации в случае процессора ADSP-BF533.

Листинг 3-2. Пример назначений секции (файл LDF).

MEMORY
{
   /* Постоянная память инструкций в (Instruction ROM) в Async Bank 0,
      находящемся вне чипа процессора */
   MEM_PROGRAM_ROM { TYPE(ROM) START(0x20000000) END(0x2009FFFF) WIDTH(8)
}
MEM_DATA_ROM
{
   /* Данные констант в Async Bank 0, находящемся вне чипа процессора */
   TYPE(ROM) START(0x200A0000) END(0x200FFFFF) WIDTH(8)
}
MEM_DATA_RAM
{
   /* Данные SRAM (память, физически находящаяся на кристалле процессора),
      не будет загружена автоматически */
   TYPE(RAM) START(0xFF903000) END(0xFF907FFF) WIDTH(8)
}

Листинг 3-3. Пример определения сегмента ROM (файл LDF).

PROCESSOR p0
{
   OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
   
   SECTIONS
   {
      program_rom
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(rom_code) )
      } >MEM_PROGRAM_ROM
      data_rom
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(rom_data) )
      } >MEM_DATA_ROM
      data_sram
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(ram_data) )
      } >MEM_DATA_RAM

С файлом LDF, модифицированным таким образом, файлы исходного кода могут теперь получить новые введенные секции, как это показано в листинге 3-4.

Листинг 3-4. Пример использования секций (файл исходного кода).

.SECTION rom_code;
_reset_vector:
               l0 = 0;
               l1 = 0;
l2 = 0; l3 = 0; /* здесь находится продолжение настройки и код приложения */ /* . . . */ .SECTION rom_data; .VAR myconst x = 0xdeadbeef; /* . . . */ .SECTION ram_data; .VAR myvar y; /* обратите внимание, что переменная y не может быть инициализирована
                  автоматически */

Встроенный в кристалл код Boot ROM процессоров Blackfin ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 позволяет загружать следующие диапазоны памяти.

Память L1
ADSP-BF531 Data bank A SRAM (0xFF80 4000–0xFF80 7FFF)
Instruction SRAM (0xFFA0 8000–0xFFA0 BFFF)
ADSP-BF532 Data bank A SRAM (0xFF80 4000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 4000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 8000–0xFFA1 3FFF)
ADSP-BF533 Data bank A SRAM (0xFF80 0000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 0000–0xFFA1 3FFF)
ADSP-BF534 Data bank A SRAM (0xFF80 0000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 0000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 0000–0xFFA1 3FFF)
ADSP-BF536 Data bank A SRAM (0xFF80 4000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 4000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 0000–0xFFA1 3FFF)
ADSP-BF537 Data bank A SRAM (0xFF80 0000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 0000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 0000–0xFFA1 3FFF)
ADSP-BF538 Data bank A SRAM (0xFF80 4000–0xFF80 7FFF)
Data bank B SRAM (0xFF90 4000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 8000–0xFFA1 3FFF)
ADSP-BF539 Data bank A SRAM (0xFF80 0000–0xFF80 3FFF)
Data bank B SRAM (0xFF90 2000–0xFF90 7FFF)
Instruction SRAM (0xFFA0 0000–0xFFA1 3FFF)
Память SDRAM
Все процессоры Bank 0 (0x0000 0000–0x07FF FFFF)

Загрузка в память scratchpad (0xFFB00000) не поддерживается.

Код пользователя должен предварительно инициализировать память SDRAM, чтобы неё можно было загрузить какие-либо данные или код.

[ADSP-BF535 On-Chip Boot ROM]

ADSP BF535 on chip Boot ROM fig36

Рис. 3-6. Процессоры ADSP-BF535: On-Chip Boot ROM.

Встроенный в кристалл процессора ADSP-BF535 код Boot ROM делает следующее (см. рис. 3-6):

1. Настраивает режим супервизора (supervisor mode) путем выхода из обработчика прерывания RESET и переходом в прерывание с самым низким приоритетом (IVG15).

2. Проверяет, был ли этот RESET программным сбросом, и если это так, то пропускается вся последовательность загрузки и делается переход в начало памяти L2 (0xF0000000) для выполнение кода. Код Boot ROM выполняет такую проверку тестированием бита 4 регистра конфигурации сброса (System Reset Configuration Register, SYSCR). Если бит 4 не установлен, то код Boot ROM выполняет полную последовательность загрузки. Если бит 4 установлен, то код Boot ROM пропускает последовательность загрузки, и передает управление по адресу 0xF0000000.

3. В случае запуска полной последовательности загрузки (если бит 4 регистра SYSCR не установлен) будут выполнены следующие действия:

• Проверка источника загрузки (внешнее устройство памяти, это либо память flash/PROM, либо память SPI) путем чтения BMODE2–0 из регистра SYSCR.
• Чтение первых 4 байт по адресу 0x0 внешнего устройства памяти. Эти 4 байта содержат счетчик байт (N), который задает количество загружаемых байт.
• Загрузка N во внутреннюю память L2, начиная с адреса 0xF0000000.
• Передача управления в начало памяти L2 (запуск выполнения загруженного кода).

Код on-chip boot ROM загружает N из внешней памяти. Эти N байт могут определить размер кода действующего приложения, или это может быть код загрузчика второго уровня, который загрузит код действующего приложения.

[Файлы загрузки без загрузчика второго уровня]

На рис. 3-11 показана структура файла загрузки для 8-битной flash/PROM или адресуемой 8 или 16 битами микросхемы SPI при загрузке без использования загрузчика второго уровня.

ADSP Blackfin Loader File fig311

Рис. 3-11. Файл загрузки для 8-битной Flash/PROM и SPI без загрузчика второго уровня.

На рис. 3-12 показана структура файла загрузки для 16-битной flash/PROM при загрузке без использования загрузчика второго уровня.

ADSP Blackfin Loader File fig312

Рис. 3-12. Файл загрузки для 16-битной Flash/PROM без загрузчика второго уровня.

[Файлы загрузки, используемые с загрузчиком второго уровня]

На рис. 3-13 показано графическое представление выходного файла загрузки для 8-битной загрузки из flash/PROM и адресуемой 8 или 16 битами загрузки из памяти SPI при наличии загрузчика второго уровня.

ADSP Blackfin Loader File fig313

Рис. 3-13. Файл загрузки для 8-битной Flash/PROM и SPI при использовании загрузчика второго уровня.

На рис. 3-14 показано графическое представление выходного файла загрузки для 16-битной загрузки из flash/PROM при наличии загрузчика второго уровня.

ADSP Blackfin Loader File fig314

Figure 3-14. Файл загрузки для 16-разрядной Flash/PROM Boot при использовании загрузчика второго уровня.

[Управление загрузкой нескольких приложений (Multi-DXE) ADSP-BF53x и ADSP-BF561]

Эта секция статьи не относится к процессорам ADSP-BF535.

Здесь описывается, как генерировать файл загрузки и загружать его для более чем одного входного файла .dxe для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 и BF561. Дополнительную информацию по процессорам ADSP-BF561 см. в разделе "ADSP-BF561 Dual-Core Application Management" [1].

Структура файла загрузки ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539 и BF561 и ревизия кристалла (silicon revision) от 0.1 и выше позволяют генерировать файл загрузки и загружать его из внешней памяти для больше чем одного блока исполняемого кода DXE на один процессор. Как показано на рис. 3-20, каждый входной файл с исполняемым кодом (executable file, расширение *.DXE) снабжается 4-байтным заголовком, к котором указано количество байт исполняемого кода, включая заголовки. Эта информация может использоваться для загрузки в процессор определенного, выбранного блока DXE из нескольких. 4-байтный блок, содержащий количество байт, инкапсулирован в 10-байтный заголовок, чтобы сохранить совместимость с silicon revision 0.0. Дополнительную информацию см. во врезке "Заголовки блоков и флаги ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539".

ADSP Blackfin Multi Application Booting Streams fig320

Рис. 3-20. Потоки загрузки с несколькими приложениями для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561.

Загрузка нескольких исполняемых файлов может быть выполнена по одному из следующих методов.

• Можно использовать для утилиты загрузки опцию загрузчика второго уровня (second-stage loader) -l userkernel.dxe. Здесь userkernel.dxe - исполняемый код DXE загрузчика второго уровня. Эта опция позволит Вам использовать свой собственный загрузчик второго уровня.

После того, как загрузчик второго уровня будет загружен во внутреннюю память через под управлением on-chip Boot ROM, этот загрузчик второго уровня получит полный контроль над процессом загрузки. Теперь загрузчик второго уровня может использовать счетчики байт в блоках DXE, чтобы загрузить любой выбранный блок DXE (или несколько DXE друг за другом) из внешней памяти.

• Можно использовать опцию блока инициализации -init filename.dxe, где filename.dxe имя исполняемого файла DXE, в котором содержится код инициализации (Init Code). Эта опция позволит Вам поменять указатель внешней памяти, и загрузить определенный DXE с задействованием Boot ROM. Достоинство этого метода в том, что свой загрузчик писать не надо, Init Code должен только уметь читать файл загрузки, декодировать в нем заголовки DXE и правильно менять указатель на нужный загружаемый DXE [2]. На процессорах ADSP-BF531 и ADSP-BF561 код инициализации представляет собой подпрограмму, написанную на ассемблере.

Ниже на листинге 3-5 приведен пример кода инициализации. Регистры R0 и R3 используются как указатели на внешнюю память, используемые кодом on-chip Boot ROM. Регистр R0 используется для загрузки из flash/PROM, и R3 для загрузки из памяти SPI. В блоке кода инициализации нужно изменить значение R0 или R3 так, чтобы они указывали на место во внешней памяти, откуда начинается код нужного приложения. После того, как процессор вернет управление из кода инициализации обратно в код Boot ROM, код Boot ROM продолжит загружать байты с места, указанного регистрами R0 или R3.

Листинг 3-5. Пример Init Code для загрузки в сценарии Multiple .dxe.

#include < defBF532.h >
.SECTION program;
/*******Pre-Init Section***************************************/
   [--SP] = ASTAT;
   [--SP] = RETS;
   [--SP] = (r7:0);
   [--SP] = (p5:0);
   [--SP] = I0;[--SP] = I1;[--SP] = I2;[--SP] = I3;
   [--SP] = B0;[--SP] = B1;[--SP] = B2;[--SP] = B3;
   [--SP] = M0;[--SP] = M1;[--SP] = M2;[--SP] = M3;
   [--SP] = L0;[--SP] = L1;[--SP] = L2;[--SP] = L3;
/**************************************************************/
/*******Init Code Section**************************************
   R0.H = старшая часть адреса места положения DXE
          (R0 для flash/PROM boot, R3 для SPI boot)
   R0.L = младшая часть адреса места положения DXE
          (R0 для flash/PROM boot, R3 для SPI boot)
***************************************************************/
/*******Post-Init Section**************************************/
   L3 = [SP++]; L2 = [SP++]; L1 = [SP++]; L0 = [SP++];
   M3 = [SP++]; M2 = [SP++]; M1 = [SP++]; M0 = [SP++];
   B3 = [SP++]; B2 = [SP++]; B1 = [SP++]; B0 = [SP++];
   I3 = [SP++]; I2 = [SP++]; I1 = [SP++]; I0 = [SP++];
   (p5:0) = [SP++];
   /* УБЕДИТЕСЬ, ЧТО СЛУЧАЙНО НЕ ВОССТАНОВИЛИ R0 для flash/PROM Boot,
      или R3 для SPI Boot */
   (r7:0) = [SP++];
   RETS = [SP++];
   ASTAT = [SP++];
/**************************************************************/
   RTS;

[Руководство по использованию загрузчика процессоров ADSP-BF53x/BF561]

Работа утилиты загрузки elfloader.exe зависит от опций, которые управляют процедурой обработки исполняемых файлов DXE. Вы выбираете такие возможности, как режим загрузки (boot mode), загрузка ядра (boot kernel), формат выходного файла и т. д. Опции указываются для утилиты загрузки через командную строку, или опосредованно через графический интерфейс диалога редактирования свойств проекта VisualDSP++ (Project Options -> Load).

Раздел Load свойств проекта состоит из нескольких подразделов. Когда Вы выбрали раздел Load, то в нем уже будут установлены некоторые установки по умолчанию для загрузчика выбранного процессора.

Настройки в разделе Load соответствуют опциям, которые будут указаны в командной строке утилиты загрузки elfloader.exe. Подсмотреть полное содержимое командной строки можно в лог-файле процесса сборки, см. подкаталог Release (или Debug), файл имя_проекта.log.

Далее в нескольких секциях будет описано, как генерировать загружаемый и не загружаемый файл загрузки:

• Использование командной строки утилиты загрузки Blackfin.
• Настройка опций генерации файла загрузки в проекте VisualDSP++.
• Using VisualDSP++ Compression (здесь этот раздел не рассматривается, см. [1]).
• Using VisualDSP++ Second-Stage Loader for ADSP-BF535 Processors (здесь этот раздел не рассматривается, см. [1]).
• Использование ROM-сплиттера VisualDSP++.

[Синтаксис командной строки elfloader.exe]

Утилита загрузки ADSP-BF5xx Blackfin использует loader следующий общий синтаксис командной строки. Для одного входного файла:

elfloader inputfile -proc processor [-опция ...]

Для нескольких входных файлов:

elfloader inputfile1 inputfile2 ... -proc processor [-опция ...]

Здесь указаны параметры:

inputfile - это имя файла исполняемого кода (с расширением .dxe), который должен быть обработан, чтобы в результате получился один загружаемый (boot-loadable) или не загружаемый (non-bootable) файл. Имя входного файла может включать имя диска (C:, D:, и т. п.) и полный путь до каталога, где находится файл (в составе пути можно также применять . и ..). Для систем с несколькими процессорами или в сценарии загрузки Multi-DXE указываются несколько входных файлов .dxe. Укажите имена входных файлов в том порядке, в котором Вы хотите, чтобы утилита загрузки их обработала. Заключайте длинные имена файлов (и имена файлов с пробелами) в двойные кавычки ("long file name").

-proc processor - здесь указывается модель процессора (например, -proc ADSP-BF532), для которого будет построен файл загрузки. Если Вы разрабатываете файл загрузки для многопроцессорной системы, то для каждого входного файла .dxe укажите модель процессора.

-опция ... - здесь указывается одна или несколько обрабатываемых опций. Опции выбирают операции и режимы для утилиты загрузки.

Опции командной строки могут появляться в командной строке в любом порядке, за исключением порядка следования входных файлов для многопроцессорной системы. Для систем со сценарием загрузки Multi-DXE утилита загрузки обрабатывает входные файлы в том порядке, в каком они были указаны в командной строке.

Пути поиска файлов. Это важный фактор для обработки файла загрузки. Утилита загрузки поддерживает относительные (т. е. относительно текущего каталога, т. е. в составе пути можно применять . и ..) и абсолютные имена каталогов, каталоги по умолчанию и каталоги, выбранные пользователем. Подробнее про обработку путей поиска см. [1], раздел "File Searches" на странице 1-17.

Расширения файлов. Некоторые опции утилиты загрузки принимают имя файла в качестве параметра опции. В таблице 3-9 перечислены ожидаемые типы файла, имена и расширения файла.

Таблица 3-9. Расширения файлов.

Расширение Описание файла
.dxe Входные файлы (содержащие исполняемый код), файлы загрузчика ядра (boot kernel) и файлы инициализации (Init Code).
.ldr Выходные файлы загрузки.
.knl Выходные файлы загрузки, содержащие код ядра, только когда выбрано два выходных файла.

В некоторых случаях утилита загрузки ожидает входные файлы оверлея (overlay input files) с расширением .ovl, входные файлы обшей памяти (shared memory input files) с расширением .sm, или и те и другие, однако не ожидается появление этих файлов в командной строке или где-нибудь в разделе Load свойств проекта. Утилита загрузки ищет эти файлы в каталоге, связанном с файлами .dxe, в текущем рабочем каталоге, или в каталоге, указанном в файле .ldf.

[Общие опции командной строки elfloader.exe]

Таблица 3-10. Основные опции командной утилиты Blackfin Loader (elfloader.exe).

Опция Описание
-b prom
-b flash
-b spi
-b spislave
-b UART
-b TWI
-b FIFO
Описывает режим загрузки, и направляет утилиту загрузки к созданию загружаемого файла для указанного режима загрузки. Допустимые режимы включают PROM, flash, SPI, SPI slave, UART, TWI и FIFO.

Режимы загрузки SPI, UART и TWI могут применяться только для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539. Режим FIFO может применяться для процессоров ADSP-BF534, BF536, BF537 начиная с silicon revision 0.4.

Если в командной строке нет опции -b, то по умолчанию подставляется опция -b flash.
-baudrate # Опция принимает скорость обмена только для загрузки через SPI. Для # допустимы следующие значения скорости:
500K - 500 кГц, значение по умолчанию
1M - 1 Мгц
2M - 2 МГц

Загрузка ядра (boot kernel loading) поддерживает скорости до 2 МГц.

Опция применима только к процессорам ADSP-BF535.
-compression Направляет утилиту загрузки сжимать поток загрузки. Для поддержки этой функции должен быть предоставлен DXE инициализации с поддержкой декомпрессии (по умолчанию или пользовательский). Подробнее см. [1].

Эта опция допустима только для режимов загрузки flash/PROM и не применима для процессоров ADSP-BF535, BF538, BF539 или BF561.
-compressWS # Указывает размер окна компрессии (Window Size) в байтах. Указанное число # является степенью 2, и используется системой сжатия. Допустимые значения 8..15 бит, по умолчанию используется 9.

Эта опция допустима только для режимов загрузки flash/PROM и не применима для процессоров ADSP-BF535, BF538, BF539 или BF561.
-dmawidth # Задает ширину передач DMA (в битах, для # можно указать 8 или 16). Для режима загрузки FIFO допустима только ширина 16. Для других режимов загрузки допустимы значения ширины 8 и 16, по умолчанию используется 8.

Не применимо к процессорам ADSP-BF535 или ADSP-BF561.
-enc dll_filename Опция шифрует поток данных приложения из входных файлов .dxe по алгоритму шифрования в файле динамически загружаемой библиотеки dll_filename. Если параметр dll_filename отсутствует в командной строке, то используется файл по умолчанию алгоритма шифрования от компании Analog Devices.
-f hex
-f ASCII
-f binary
-f include
Задает формат выходного файла загрузки (Intel hex-32, ASCII, binary, include). Если в командной строке опция -f отсутствует, то по умолчанию применяется формат hex для flash/PROM и ASCII для SPI, SPI slave, UART и TWI.
-ghc # Опция в параметре # задает 4-битное значение (global header cookie) для битов 31..28 глобального заголовка (см. таблицу 3-7 в [1]).

Применимо только к процессорам ADSP-BF561.
-h
-help
В ответ на эту опцию утилита загрузки выдаст подсказку - список опций командной строки. По умолчанию, если только указать опцию -h (или -help), то будет выведена подсказка по драйверу загрузки. Чтобы получить подсказку по Вашему целевому процессору, добавьте в командную строку опцию -proc. Например, для подсказки по процессору ADSP-BF535 введите:

elfloader -proc ADSP-BF535 -h
-HoldTime # Указывает количество циклов времени удержания для загрузки flash/PROM. Для # допустимы значения от 0 до 3 (значение по умолчанию 3).

Применимо только для процессоров ADSP-BF535.
-init файл.dxe Задает подключить файл инициализации (Init Code), утилита загрузки поместит код из секций инициализации, находящихся в указанном файле DXE, в выходной поток загрузки. Ядро загрузит этот код и затем запустит его. В зоне ответственности загруженного Init Code находится использование регистров, их сохранение на входе и восстановление на выходе. Код Init Code должен завершаться инструкцией RTS для возврата управления ядру.

Не применимо для процессоров ADSP-BF535.
-kb prom
-kb flash
-kb spi
-kb spislave
-kb UART
-kb TWI
-kb FIFO
Опция задает режим загрузки (PROM, flash, SPI, SPI slave, UART, TWI или FIFO) для выходного файла загрузки ядра, если Вы генерируете 2 выходных файла с помощью утилиты загрузки: один для загрузчика ядра, и другой для кода приложения.

Параметры spislave, UART и TWI применимы только для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538 и BF539. Параметр FIFO применим для процессоров ADSP-BF534, BF536, BF537 начиная с silicon revision 0.4.

Опция -kb должна использоваться вместе с опцией -o2.

Если опция -kb отсутствует в командной строке, утилита загрузки генерирует файл для загрузчика ядра в том же самом режиме загрузки, который используется для выходного файла загрузки основной программы.
-kf hex
-kf ascii
-kf binary
-kf include
Задает формат выходного файла (hex, ASCII, binary или include) для загрузчика ядра, если утилита загрузки генерирует 2 выходных файла: один для загрузчика ядра, другой для кода приложения.

Опция -kf должна использоваться вместе с опцией -o2.

Если опция -kb отсутствует в командной строке, утилита загрузки генерирует файл для загрузчика ядра в том же самом режиме загрузки, который используется для выходного файла загрузки основной программы.
-kenc dll_filename Задает пользовательский файл библиотеки шифрования потока данных из файла ядра. Если параметр dll_filename отсутствует в командной строке, то используется файл по умолчанию алгоритма шифрования от компании Analog Devices.
-kp # Задает стартовый адрес (в формате HEX) выходного кода ядра. Допустимое значение между 0x0 и 0xFFFFFFFF. Указанное значение игнорируется, когда в файл загрузки не подключается ядро и/или код инициализации.
-kWidth # Задает ширину шины данных для выходного файла загрузки ядра, когда утилита загрузки генерирует 2 выходных файла: один для загрузчика ядра, и другой для основного приложения. Допустимы значения:
• 8 или 16 для загрузки ядра в режимах PROM или flash
• 16 для режима загрузки ядра FIFO
• 8 для SPI и других режимов загрузки ядра

Если в командной строке отсутствует эта опция, то используются следующие значения по умолчанию:
• Параметр -width для режима загрузки flash/PROM
• 16 для режима загрузки FIFO
• 8 для SPI или других режимов загрузки.

Опция -kWidth должна использоваться вместе с опцией -o2.
-l userkernel.dxe Указывает пользовательский файл загрузки ядра. Утилита загрузки использует указанное пользователем ядро и игнорирует загрузчик ядра по умолчанию, если загрузчик указан пользователем.

В настоящий момент только процессор ADSP-BF535 имеет загрузчик ядра по умолчанию.
-M Опция задает генерировать только зависимости make, выходной файл загрузки не будет сгенерирован.
-maskadr # Опция маскирует (обнуляет) все биты адреса EEPROM, номера которых больше или равны #. Например, -maskaddr 29 (значение по умолчанию) маскирует все старшие биты адреса начиная с A29 включительно (на адрес будет наложена по операции И маска 0x1FFFFFFF). Например, в этом случае адрес 0x20000000 превратится в адрес 0x00000000. Для # допустимы целые числа от 0 до 32, однако на базе конкретного входного файла значение может быть выбрано из подмножества [0, 32].

Опция -maskaddr # требует наличия опции -romsplitter и влияет только на адрес секции ROM.
-MaxBlockSize # Задает максимальный размер блока в байтах, который должен делиться нацело на 16.
-MaxZeroFillBlockSize # Указывает максимальный размер блока для блоков, заполняемых нулями. Для # допустимы значения от 0x0 до 0xFFFFFFF0, и значение по умолчанию соответствует опции -MaxBlockSize #.
-MM Генерирует зависимости make, а также выходной файл загрузки.
-Mo filename Опция задает запись зависимостей make в указанный файл. Используйте эту опцию вместе с опциями -M либо -MM. Если опция -Mo отсутствует, то по умолчанию вывод будет произведен в поток stdout (окно консоли командной строки).
-Mt filename Задает зависимости make целевого выходного файла. Используйте эту опцию вместе с опциями -M либо -MM. Если опция -Mt отсутствует, то по умолчанию используется имя входного файла с расширением *.ldr.
-no2kernel Опция генерирует выходной файл без загрузчика ядра, но использует код загрузки из внутреннего Boot ROM. Поток загрузки, генерируемый утилитой загрузки, будет отличаться от потока загрузки, генерируемого для загрузчика ядра.

Опция относится только к процессорам ADSP-BF535.
-noFinalBlock Задает не создавать специальный завершающий блок для загрузки TWI.

Опция относится только к процессорам ADSP-BF537.
-noFinalTag Задает не устанавливать тег завершающего блока для первого файла *.dxe. В результате процесс загрузки продолжается со второго файла *.dxe, который следует за первым.

Опция относится только к процессорам ADSP-BF56x.
-noInitCode Задает не ожидать входного файла для Init Code, даже когда секция внешней памяти присутствует во входном файле *.dxe.

Применимо только к процессорам BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539.
-noSecondStageKernel Указывает не включать ядро второй стадии загрузки в выходной поток файла загрузки.

Применимо только к процессорам ADSP-BF56x.
-o filename Задает использовать указанное имя для генерируемого выходного файла загрузки. Если параметр filename отсутствует, то будет использоваться по умолчанию корневое имя входного файла, и выходной файл получит расширение *.ldr.
-o2 Задает генерировать 2 файла: один для блока инициализации (если он есть) и загрузчика ядра, и другой для основного приложения. Чтобы задать другой формат, режим загрузки, или выходной ширины, которые отличаются от выходного файла приложения, используйте опции -kb, -kf, -kwidth.

Не комбинируйте опцию -o2 с опцией -nokernel для процессоров ADSP-BF535. Комбинируйте -o2 с -l filename и/или -init filename для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561.
-p address Задает стартовый адрес (в HEX-формате) для flash/PROM кода приложения. Для address допустимо значение между 0x0 и 0xFFFFFFFF. Указанное значение должно быть больше, чем указано опцией -kp, если оба кода загрузчика ядра и/или кода инициализации находятся в одном и том же выходном файле (генерируется один выходной файл).
-pFlag #
-pFlag PF#
-pFlag PG#
-pFlag PH#
Опция в # задает 4-битное шестнадцатеричное значение для строба (программируемого флага) или для одного из портов F, G или H. Для этой опции нет значения по умолчанию. Значение зависит от процессора, его silicon revision, режима загрузки, ширины шины данных, и может меняться. Утилита загрузки выдаст предупреждение для недопустимых комбинаций. В таблицах 3-11, 3-12, 3-13 показаны допустимые значения для опции -pFlag.

Применимо только для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561.
-proc processor Задает модель используемого целевого процессора. Допустимы следующие значения для параметра processor: ADSP-BF531, ADSP-BF532, ADSP-BF533, ADSP-BF534, ADSP-BF535, ADSP-BF536, ADSP-BF537, ADSP-BF538, ADSP-BF539, ADSP-BF561.
-romsplitter Опция побуждает утилиту загрузки работать как сплиттер. Т. е. она создает не загружаемый образ (чистый двоичный код). Эта опция отменяет действие опции -b и любые другие опции, относящиеся к загрузке кода.

В файле настроек линкера *.ldf декларируйте сегменты памяти как 'split' для типа ROM. Сплиттер пропускает сегменты RAM, в результате получится пустой файл, если все сегменты декларированы как RAM. Опция -romsplitter поддерживает форматы hex и ASCII.
-ShowEncryptionMessage Отображает сообщение, которое возвращено из функции шифрования.
-si-revision #|none|any Задает ревизию кристалла (silicon revision) для указанного (опцией -proc) процессора. Параметр принимает 3 формы:

• Значение none показывает, что VisualDSP++ будет игнорировать вариации заплаток ошибок кремния (silicon errata).
• Значение # принимает одну или несколько десятичных цифр, за которыми следует точка и еще одна или несколько десятичных цифр. Это задает ревизию кристалла, например: 0.0, 1.12, 23.1. Ревизия 0.1 отличается от ревизии 0.10, и она меньше, чем 0.10. Цифра слева от точки задает номер chip tapeout, цифра справа задает номер ревизии металлической маски. Число справа от точки не может превышать 255.
• Значение any показывает, что VisualDSP++ генерирует выходной файл, который может быть запущен на любой ревизии кремния.

Опция генерирует либо предупреждение по любой возможной аномалии процессора, либо ошибку, если точно возникнет ошибка, связанная с аномалией ревизии кристалла.

Если опция ревизии кристалла отсутствует, то утилита загрузки выбирает самую высокую известную для неё ревизию кристалла, если таковая имеется.
-v Задает выдавать подробные сообщения загрузчика и процесса обработки файлов.
-waits # Задает количество циклов ожидания для доступа через внешнюю шину. Допустимы значения от 0 до 15. Циклы ожидания применимы только для режима загрузки flash/PROM.

Опция относится только к процессорам ADSP-BF535.
-width # Задает ширину шины данных для выходных файлов загрузки в битах. Для # допустимы значения 8 и 16, в зависимости от режима загрузки. Значение по умолчанию 16 для режима загрузки FIFO и 8 значение по умолчанию для всех других режимов загрузки.

На процессорах ADSP-BF535 опция не влияет на обработку загрузки кода ядра. Утилита загрузки обрабатывает ядро с шириной 8 бит, независимо от выбора выходной ширины файла.

• Для загрузки flash/PROM размер выходного файла зависит от опции -width #.
• Для загрузки FIFO для опции можно использовать только значение 16.
• Для загрузки SPI размер выходного файла *.ldr тот же для обоих -width 8 и -width 16. Различие только в информации заголовка.
-ZeroPadForced Опция задает дополнять каждый байт данных нулевым байтом при генерации 16-битного вывода. Используйте эту опцию только если Ваша система требует в файле загрузки дополнения нулями. Будьте осторожны: добавление нулевых байт может привести к сбою загрузки. Обычно дополнение нулями утилита делает автоматически, в зависимости от режима загрузки и других опций.

Опция применима только к процессорам ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539.

Таблица 3-11. Значения -pFlag для процессоров ADSP-BF531/BF532/BF533(1).

Silicon revision 0.0 - 0.2
0.3 - 0.5
Width 8 16 8 16
Режим загрузки flash NONE NONE NONE NONE
Режим загрузки SPI NONE   NONE  
Подчиненный режим загрузки SPI
(SPI slave boot)
    1-15
PF1-15
 

Примечание (1): для процессоров ADSP-BF531, BF532, BF533 бит RESVECT (бит 2 в поле флагов заголовка блока) всегда очищен (==0).

Таблица 3-12. Значения -pFlag для процессоров ADSP-BF534, BF536, BF537(2).

Silicon revision 0.0
0.1 - 0.2
0.3
Width 8 16 8 16 8 16
Режим загрузки flash NONE NONE NONE
PF0-15
PG0-15
PH0-15
NONE
PF0-15
PG0-15
PH0-15
NONE
PF0-15
PG0-15
PH0-15
NONE
PF0-15
PG0-15
PH0-15
Режим загрузки SPI NONE   NONE   NONE
PF0-9
PF15
PG0-15
PH0-15
 
Подчиненный режим загрузки SPI
(SPI slave boot)
1-15
PF1-15
  NONE
PF0-10
PF15
PG0-15
PH0-15
 

NONE
PF0-10
PF15
PG0-15
PH0-15
 
Режим загрузки TWI NONE   NONE
PF0-15
PG0-15
PH0-15
 

NONE
PF0-15
PG0-15
PH0-15
 
Подчиненный режим загрузки TWI
(TWI slave boot)
NONE   NONE
PF0-15
PG0-15
PH0-15
 

NONE
PF0-15
PG0-15
PH0-15
 
Режим загрузки UART 2-15
PF2-15
  NONE
PF2-15
PG0-15
PH0-15
 

NONE
PF2-15
PG0-15
PH0-15
 
Режим загрузки FIFO        

  NONE
PF0
PF2-15
PG0-15
PH0-15

Примечание (2): для процессоров ADSP-BF534, BF536, BF537 бит RESVECT (бит 2 в поле флагов заголовка блока) всегда установлен (==1).

Таблица 3-13. Значения -pFlag для процессоров ADSP-BF538, BF539(3).

Silicon revision 0.0 - 0.3
Width 8 16
Режим загрузки flash NONE NONE
Режим загрузки SPI NONE  
Подчиненный режим загрузки SPI
(SPI slave boot)
1-15
PF1-15
 

Примечание (3): для процессоров ADSP-BF538, BF539 бит RESVECT (бит 2 в поле флагов заголовка блока) всегда установлен (==1).

Все настройки опций загрузки проекта делаются через диалог редактирования свойств проекта (меню Project -> Project Options...).

Сначала нужно выбрать генерацию файла загрузки Loader file (.ldr) в качестве выходного типа компиляции проекта Вашего приложения (главный раздел опций Project, блок Target, параметр Type: Loader file). Аналогичный выбор делается в мастере (VisualDSP++ Project Wizard) при создании проекта приложения.

После этого можно редактировать опции в разделе Load свойств проекта.

VisualDSP Load options page for ADSP BF535 fig326

Рис. 3-26. Опции Load свойств проекта для процессоров ADSP-BF535.

Настройки раздела Load в дереве опций проекта состоят из нескольких страниц. Когда Вы откроете страницу Load -> Options (которая также называется страницей свойств загрузчика, "loader property page"), просмотрите настройки по умолчанию для загрузки. Как показано в примере на рис. 3-26 значения загрузки по умолчанию для процессора ADSP-BF535 рассчитаны на загрузку из PROM. Опции диалога имеют аналоги опций командной строки утилиты загрузки elfloader.exe. Обратитесь к таблице 3-10 для получения подробной информации по опциям командной строки утилиты загрузки.

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

Таблица 3-14. Базовые настройки страницы Load свойств проекта для процессоров ADSP-BF53x/BF561.

Опция настройки Описание
Load Варианты выбора, касающиеся основного поведения утилиты загрузки.
• Options - опции загрузки по умолчанию (относится к этому разделу)
• Compression – выбор стандарта сжатия для zLib; применимо к процессорам ADSP-BF531, BF532, BF533, BF534, BF536 и BF537 (см. [1]). Компрессия недоступна для проектов на основе ASDP-BF535.
• Kernel – спецификация для загрузчика второго уровня. Может использоваться для переназначения загрузки ядра по умолчанию, как это применяется для процессоров ADSP-BF535.
• Splitter – спецификация для режима без загрузки (no-boot mode). Если Вы не используете загрузку ядра (kernel) на процессорах ADSP-BF535, то на странице Kernel все опции ядра будут не доступны для редактирования (будут серыми). Утилита загрузки не делает поиск boot kernel, если Вы используете загрузку из встроенного в кристалл ROM путем задания опции командной строки -no2kernel.
Для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561, у которых нет программного обеспечения для загрузки ядра по умолчанию, выберите один из загрузчиков ядра.
Boot mode Режим загрузки. Указывается в качестве источника для загрузки flash/PROM, SPI, SPI slave, UART, TWI или FIFO.
Boot format Определяет формат выходного файла загрузки. Можно выбрать Intel HEX, ASCII, include или binary.
Output width Можно указать ширину шины данных: 8 или 16 бит. Если BMODEx = 01 или 001, и микросхема flash/PROM имеет ширину шины данных 16 бит, то нужно выбрать 16 бит.
Wait state Задает количество циклов ожидания для доступа через внешнюю шину (0..15). Выбор работает для процессоров ADSP-BF535. Для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561 выбор не доступен (поле будет серым).
Baud rate Задает скорость обмена для загрузки SPI (500 кГц, 1 МГц, 2 МГц). Выбор работает для процессоров ADSP-BF535. Для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561 поле будет серым.
Hold time Указывает количество циклов времени удержания (0..3) для загрузки из flash/PROM. Выбор работает для процессоров ADSP-BF535. Для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539, BF561 поле будет серым.
Programmable flag Задает то же самое, что и опция командной строки -pFlag, т. е. выбирает номер программируемого флага (0..15) для строба или для порта. Бокс опции активен для процессоров ADSP-BF531, BF532, BF533, BF534, BF536, BF537, BF538, BF539. Допустимые значения перечислены в таблицах 3-11, 3-12, 3-13. Доступна также опция NONE; она соответствует отсутствию опции -pFlag в командной строке.
Проверьте эту настройку всякий раз, когда меняются процессор, ревизия кристалла (silicon revision), режим загрузки (boot mode) или ширина шины (width).
Use default start address Указывает выходной адрес старта по умолчанию flash/PROM кода приложения (в HEX-формате).
Start address Указывает выходной адрес старта flash/PROM кода приложения (в HEX-формате).
Verbose Генерирует информацию состояния о том, как утилита загрузки обрабатывает файлы.
Initialization file Указывает утилите загрузки подключать файл кода инициализации (Init Code).
Use default decompression INIT file Указывает утилите загрузки подключать файл кода инициализации декомпрессии по умолчанию (Init Code). Выбор активен для процессоров ADSP-BF531, BF532, BF533 и BF561. Для процессоров ADSP-BF535 поле выбора будет серым (запрещенным).
Output file Задает имя выходного файла утилиты загрузки.
Additional options Указывает дополнительные опции управления утилитой загрузки. Вы можете указать дополнительные входные файлы DXE. Введите имена входных файлов с полными путями, если файлы не находятся в текущей рабочей директории, отделите друг от друга два имени файла пробелом.

Примечание: утилита загрузки обрабатывает входные файлы в том порядке, в каком они появились в командной строке, составляемой от данных, указанных на странице свойств проекта.

В отличие от утилиты загрузки, сплиттер никак не форматирует данных приложения, когда преобразует файл исполняемого кода .dxe в файл загрузки .ldr. Он только поставляет на выходе сырые данные. Какие будут обработаны данные - то ли исполняемый код приложения, то ли данные приложения - зависит от команды TYPE() файла LDF. Секции, декларированные с командой TYPE(RAM), будут потребляться утилитой загрузки, а секции, декларированные через TYPE(ROM), будут потребляться сплиттером.

На рис. 3-29 показан диалог настройки Load -> Splitter, где настраиваются опции ROM-сплиттера. Когда не поставлена галочка Enable ROM splitter, будут обработаны только секции TYPE(RAM), и все сегменты TYPE(ROM) будут игнорированы утилитой загрузки. Если галочка Enable ROM splitter установлена, то секции TYPE(RAM) игнорируются, и утилитой сплиттера будут обработаны секции TYPE(ROM).

VisualDSP Load splitter page for ADSP BF533 fig329

Рис. 3-29. Страница настроек проекта в разделе Load -> Splitter для процессоров ADSP-BF533.

Поле Mask Address маскирует все биты адреса EPROM, которые больше или равны указанному числу. Например, Mask Address = 29 (значение по умолчанию) маскирует все биты выше и включая A29 (операция AND между адресом и константой 0x1FFFFFFF). Таким образом, адрес 0x20000000 становится равным 0x00000000. Допустимо указывать целый числа от 0 до 32, однако на базе Вашего конкретного входного файла значение может быть в подмножестве от [0, 32].

Для выбора варианта без загрузки внешние выводы процессора BMODEx должны быть притянуты к состоянию 000 для процессоров ADSP-BF535 или 00 для процессоров ADSP-BF531, ADSP-BF532 и ADSP-BF533. В этом режиме работы пропускается встроенный в кристалл код загрузки Boot ROM, и процессор сразу приступает к выборке и выполнению команд с адреса 0x20000000, находящихся в асинхронном банке 0. Процессор подразумевает, что подключена 16-битная память, где записаны допустимые инструкции (команды) для процессора.

Чтобы создать корректный файл .ldr, который можно записать либо в устройство параллельной памяти flash, либо параллельной памяти EPROM, Вы должны изменить стандартный файл LDF, чтобы вектор сброса был размещен соответствующим образом. Следующие фрагменты кода (листинги 3-6 .. 3-7) показывают необходимые модификации в случае процессора ADSP-BF533.

Листинг 3-6. Пример назначения секций (файл LDF).

MEMORY
{
   /* ROM инструкций в Async Bank 0, находящееся вне чипа */
   MEM_PROGRAM_ROM
   {
      TYPE(ROM) START(0x20000000) END(0x2009FFFF) WIDTH(8)
   }
   /* Данные констант в Async Bank 0, находящиеся вне чипа */
   MEM_DATA_ROM
   {
      TYPE(ROM) START(0x200A0000) END(0x200FFFFF) WIDTH(8)
   }
   /* Данные SRAM, находящиеся на кристалле, не могут быть загружены автоматически */
   MEM_DATA_RAM
   {
      TYPE(RAM) START(0xFF903000) END(0xFF907FFF) WIDTH(8)
   }
   ...

Листинг 3-7. Пример определений сегмента ROM (файл LDF).

PROCESSOR p0
{
   OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
   
   SECTIONS
   {
      program_rom
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(rom_code) )
      } >MEM_PROGRAM_ROM
      data_rom
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(rom_data) )
      } >MEM_DATA_ROM
      data_sram
      {
         INPUT_SECTION_ALIGN(4)
         INPUT_SECTIONS( $OBJECTS(ram_data) )
      } >MEM_DATA_RAM
      ...

С файлом LDF, измененным таким образом, исходные файлы могут получить в распоряжение новые созданные секции, как это показано в листинге 3-8.

Листинг 3-8. Пример использования секций (файл исходного кода).

.SECTION rom_code;
_reset_vector:
   l0 = 0;
   l1 = 0;
   l2 = 0;
   l3 = 0;
   /* В этом месте может быть код для начальных настроек,
      и далее код приложения */
   /* . . . */
.SECTION rom_data;
.VAR myconst x = 0xdeadbeef;
   /* . . . */
.SECTION ram_data;
.VAR myvar y; /* обратите внимание, что переменная y не может быть
                 автоматически инициализирована  */

[Практические примеры расшифровки дампов файлов загрузки]

Из всего вышесказанного следует, что модули исполняемого кода *.dxe можно по отдельности преобразовывать в двоичные файлы, и записывать в любое произвольное место памяти, откуда происходит загрузка (загрузочная память). Т. е. двоичный код файлов загрузки никак не привязан к адресам загрузочной памяти, в ней можно сколько угодно разместить файлов загрузки, и в любом порядке, и даже с пропусками между ними. Главное условие - правильно управлять кодом Boot ROM, инициализируя регистр R0 (или R3, в зависимости от типа используемой загрузочной памяти) нужным абсолютным адресом загрузочной памяти.

Ниже будут рассмотрены несколько примеров дампов файлов загрузки. В этих 3 примерах исполняемый код из файлов с расширением *.dxe преобразуются в загрузочные файлы с расширением *.ldr в двоичном формате с помощью elfloader.exe, вызываемой из командной строки.

Командная строка elfloader:

@rem Генерация LDR-файла для Init Code в формате BIN:
@"C:\Program Files (x86)\Analog Devices\VisualDSP 5.0\elfloader.exe" .\Init_Sdram\Release\sdram.dxe
 -b Flash -f binary -Width 16 -o .\bin\sdram.ldr -si-revision 0.5 -proc ADSP-BF538 -MM

В этом примере код инициализации SDRAM скомпилирован как обычная программа, без добавления кода инициализации (опция -init отсутствует). Это сделано только в целях демонстрации, потому что проект Init Code дает маленький, удобный для рассмотрения двоичный код. В результатом работы утилиты elfloader будет файл загрузки, который показан на скриншоте ниже.

ldr Init Code as main program

Отдельные части файла загрузки для наглядности выделены разными цветами. Давайте рассмотрим, что они означают.

Адрес Байты дампа Описание
00000000 600080FF С этих байт начинается заголовок блока 0. Это поле ADDRESS, первый байт 60 показывает, что это файл загрузки из FLASH. Остальные байты ничего не означают.
00000004 04000000 COUNT==4 байта, означает, что после поля FLAG будет 4 байта полезных данных (количество байт в модуле DXE). Обратите внимание, что в COUNT не учитывает размер заголовка блока.
00000008 1200 FLAG, флаги показывают, что это блок типа IGNORE, т. е. его не надо загружать в память. Этот блок просто говорит, сколько байт всего в модуле DXE.
0000000A A4000000 Данные блока 0, здесь записано, что размер модуля DXE 164 байта (164 == 0xA4). Следующий блок (Блок 1) начнется с адреса 10 + 4, т. е. с адреса 0x0000000E.
0000000E 0080A0FF Начало заголовка блока 1. Поле ADDRESS, задает положение блока кода в SRAM инструкций по адресу 0xFFA08000.
00000012 9A000000 COUNT==154 говорит, что в этом блоке всего 154 байта полезных данных (154 == 0x9A). Обратите внимание, что COUNT не учитывает размер заголовка блока.
00000016 0280 FLAG, говорит что это последний блок.
00000018 660167.. Далее до конца файла идут данные блока 1, которые загрузчик поместит в SRAM по адресу, указанному в поле ADDRESS.

Командная строка elfloader:

@rem Генерация LDR-файла для Init Code в формате BIN:
@"C:\Program Files (x86)\Analog Devices\VisualDSP 5.0\elfloader.exe" -init .\Init_Sdram\Release\sdram.dxe
 -b Flash -f binary -Width 16 -o .\bin\sdram-init-code.ldr -si-revision 0.5 -proc ADSP-BF538 -MM

В этом примере код инициализации SDRAM скомпилирован как Init Code (с опцией -init), без добавления кода основной программы. Этот пример полезен, потому что может использоваться в реальных проектах.

ldr Init Code only

Адрес Байты дампа Описание
00000000 600080FF С этих байт начинается заголовок блока 0. Это поле ADDRESS, первый байт 60 показывает, что это файл загрузки из FLASH. Остальные байты ничего не означают.
00000004 04000000 COUNT==4 байта, означает, что после поля FLAG будет 4 байта полезных данных (количество байт в модуле DXE). Обратите внимание, что в COUNT не учитывает размер заголовка блока.
00000008 1200 FLAG, флаги показывают, что это блок типа IGNORE, т. е. его не надо загружать в память. Этот блок просто говорит, сколько байт всего в модуле DXE.
0000000A B0000000 Данные блока 1, здесь записано, что размер модуля DXE 176 байт (176 == 0xB0). Следующий блок (Блок 1) начнется с адреса 10 + 4, т. е. с адреса 0x0000000E.
0000000E 0080A0FF Начало заголовка блока 1. Поле ADDRESS, задает положение блока кода в SRAM инструкций по адресу 0xFFA08000.
00000012 9A000000 COUNT==154 говорит, что в этом блоке всего 154 байта полезных данных (154 == 0x9A). Обратите внимание, что COUNT не учитывает размер заголовка блока.
00000016 0200 FLAG, говорит что это не последний блок.
00000018 660167.. Далее идут данные блока 1, которые загрузчик поместит в SRAM по адресу, указанному в поле ADDRESS.

До настоящего момента все почти совпадает с предыдущим примером (Пример 1), но в этом примере появляется еще и последний блок 2.

000000B2 0080A0FF Начало заголовка блока 2. Поле ADDRESS.
000000B6 02000000 COUNT==2 говорит, что в этом блоке всего 2 байта полезных данных.
000000BA 0A00 FLAG, говорит, что это блок INIT.
000000BC 6601 Некий магический, ничего не означающий набор байт. Почему-то так всегда завершается Init Code.

Командная строка elfloader:

@rem Генерация совмещенного Init Code + основная программа в формате BIN:
@"C:\Program Files (x86)\Analog Devices\VisualDSP 5.0\elfloader.exe" .\BF538\Release\main.dxe
 -b Flash -f binary -Width 16 -init .\Init_Sdram\Release\sdram.dxe -o .\bin\sdram-init-code-and-main.ldr
-si-revision 0.5 -proc ADSP-BF538 -MM

В этом примере в выходной файл загрузки попало два модуля DXE: Init Code (sdram.dxe, DXE0) и код основной программы (main.dxe, DXE1).

ldr Init Code and main program

Адрес Байты дампа Описание
00000000 600080FF С этих байт начинается заголовок блока 0. Это поле ADDRESS, первый байт 60 показывает, что это файл загрузки из FLASH. Остальные байты ничего не означают.
00000004 04000000 COUNT==4 байта, означает, что после поля FLAG будет 4 байта полезных данных (количество байт в модуле DXE). Обратите внимание, что в COUNT не учитывает размер заголовка блока.
00000008 1200 FLAG, флаги показывают, что это блок типа IGNORE, т. е. его не надо загружать в память. Этот блок просто говорит, сколько байт всего в модуле DXE.
0000000A B0000000 Данные блока 1, здесь записано, что размер модуля DXE0 равен 176 байт (176 == 0xB0). Следующий блок (Блок 1) начнется с адреса 10 + 4, т. е. с адреса 0x0000000E.
0000000E 0080A0FF Начало заголовка блока 1. Поле ADDRESS, задает положение блока кода в SRAM инструкций по адресу 0xFFA08000.
00000012 9A000000 COUNT==154 говорит, что в этом блоке всего 154 байта полезных данных (154 == 0x9A). Обратите внимание, что COUNT не учитывает размер заголовка блока.
00000016 0200 FLAG, говорит что это не последний блок.
00000018 660167.. Далее идут данные блока 1, которые загрузчик поместит в SRAM по адресу, указанному в поле ADDRESS.
000000B2 0080A0FF Начало заголовка блока 2. Поле ADDRESS.
000000B6 02000000 COUNT==2 говорит, что в этом блоке всего 2 байта полезных данных.
000000BA 0A00 FLAG, говорит, что это блок INIT.
000000BC 6601 Некий магический, ничего не означающий набор байт. Почему-то так всегда завершается Init Code.

Пока все почти полностью совпадает с предыдущим примером (Пример 2), это были блоки исполняемого модуля Init Code (DXE0). В этом же примере в файл загрузки добавлен также код основной программы, поэтому далее идут блоки основной программы (DXE1).

000000BE 600080FF С этих байт начинается заголовок блока 0 программы DXE1. Это поле ADDRESS, первый байт 60 показывает, что это файл загрузки из FLASH. Остальные байты ничего не означают.
000000C2 04000000 COUNT==4 байта, означает, что после поля FLAG будет 4 байта полезных данных (количество байт в модуле DXE1). Обратите внимание, что в COUNT не учитывает размер заголовка блока.
000000C6 1200 FLAG, флаги показывают, что это блок типа IGNORE, т. е. его не надо загружать в память. Этот блок просто говорит, сколько байт всего в модуле DXE1.
000000C8 20820000 Данные блока 0, здесь записано, что размер модуля DXE1 равен 33312 байт (33312 == 0x8220). Следующий блок (Блок 1) начнется с адреса 0xC8 + 4, т. е. с адреса 0x000000CC.
000000CC 04000000 Начало заголовка блока 1. Поле ADDRESS, задает положение блока в SDRAM по адресу 0x00000004.
000000D0 00240000 COUNT==9216 говорит, что в этом блоке всего 9216 байта полезных данных (9216 == 0x2400).
000000D4 0300 FLAG, говорит, что это блок Zero Fill. Т. е. 9216 байт должны быть заполнены нулями.
000000D6 000080FF Начало заголовка блока 2. Поле ADDRESS, задает положение блока в SRAM по адресу 0xFF800000.
000000DA 02000000 COUNT==2 говорит, что в этом блоке всего 2 байта полезных данных.
000000DE 0200 FLAG, говорит, что это обычный блок.
000000E0 0000 Данные блока 2.
000000E2 000180FF Начало заголовка блока 3. Поле ADDRESS, задает положение блока в SRAM по адресу 0xFF800100.
000000E6 1С000000 COUNT==28 говорит, что в этом блоке всего 28 байт полезных данных (28 == 0x1C).
000000EA 0300 FLAG, говорит, что это блок Zero Fill. Т. е. 28 байт должны быть заполнены нулями.
........ ... Далее идут блоки 4..26.
000017E6 0000A0FF Начало заголовка блока 27. Поле ADDRESS, задает положение блока в SRAM по адресу 0xFFA00000.
000017EA FC6A0000 COUNT==27388 говорит, что в этом блоке всего 27388 байт полезных данных (27388 == 0x6AFC).
000017EE 0280 FLAG, говорит что это последний блок.
000017F0 21E100.. Данные блока 27, продолжаются до конца файла загрузки.

В этом примере показан код, который возвращает управление в Boot ROM процессора, передавая в регистре R0 адрес начала DXE, который следует загружать. Загрузка происходит из памяти FLASH, поэтому для адреса используется регистр R0 (для загрузки по SPI для адреса используется регистр R3). Поскольку FLASH находится по абсолютному адресу 0x20000000 в адресном пространстве Blackfin, то в R0 записывается адрес 0x20004000, который указывает место положения загружаемого кода DXE.

Обратите внимание, как происходит на выходе коррекция стека, чтобы не затиралось установленное значение регистра R0.

#include < defBF532.h >
 
.section program;
.EXTERN _InitSDRAM;
 
start:
   [--SP] = ASTAT;
   [--SP] = RETS;
   [--SP] = (r7:0);
   [--SP] = (p5:0);
   [--SP] = I0;
   [--SP] = I1;
   [--SP] = I2;
   [--SP] = I3;
   [--SP] = B0;
   [--SP] = B1;
   [--SP] = B2;
   [--SP] = B3;
   [--SP] = M0;
   [--SP] = M1;
   [--SP] = M2;
   [--SP] = M3;
   [--SP] = L0;
   [--SP] = L1;
   [--SP] = L2;
   [--SP] = L3;
   CALL _InitSDRAM;
   R0.H = 0x2000;
   R0.L = 0x4000;
   L3 = [SP++];
   L2 = [SP++];
   L1 = [SP++];
   L0 = [SP++];
   M3 = [SP++];
   M2 = [SP++];
   M1 = [SP++];
   M0 = [SP++];
   B3 = [SP++];
   B2 = [SP++];
   B1 = [SP++];
   B0 = [SP++];
   I3 = [SP++];
   I2 = [SP++];
   I1 = [SP++];
   I0 = [SP++];
   (p5:0) = [SP++];
   //(r7:0) = [SP++];
   (r7:1) = [SP++];
   RETS = [SP++];    // Модификация SP на 1 в случае R0 (загрузка из FLASH)
   RETS = [SP++];
   ASTAT = [SP++];
 
END:
   RTS;

Размещение кода основной программы по известному абсолютному адресу загрузочной памяти удобно для обновления программы. В нашем примере это адрес 0x4000, который соответствует следующему сектору памяти FLASH (размер сектора равен 0x4000, т. е. 16384 байта).

Этот адрес выбран не случайно - как известно, память FLASH записывается сразу секторами. Т. е. загрузчик, который обновляет основную программу, вместе с кодом инициализации записан в секторе 0 (адреса 0x0000..0x3FFF), и он при обновлении не перетирается. Код основной программы находится в секторах остальной памяти, начиная с сектора 1 (т. е. с адреса 0x4000), и перепрошивка основной программы никак не запортит код загрузчика.

[Ссылки]

1. VisualDSP++ 5.0 Loader and Utilities Manual site:analog.com.
2. Как происходит загрузка ADSP-BF533 Blackfin.
3. Blackfin ADSP-BF538.
4. ADSP-BF538: блок интерфейса внешней шины.

 

Добавить комментарий


Защитный код
Обновить

Top of Page