Как происходит загрузка ADSP-BF533 Blackfin Печать
Добавил(а) microsin   

Здесь приведен перевод даташита EE-240 [1], описывающего процесс загрузки процессора Blackfin. С некоторыми оговорками материал подойдет для всех процессоров Blackfin. Напрямую информация касается процессоров ADSP-BF531, ADSP-BF532 и ADSP-BF533. Также даны примечания, касающиеся отдельных ревизий кристаллов (Silicon Revision). Все непонятные сокращения и термины см. в разделах "Словарик" статей [4, 5].

В EE-240 рассматриваются следующие вопросы:

• Режимы загрузки (boot modes).
• Информация в заголовке файла загрузки (Loader file).
• Код инициализации.
• Управление несколькими приложениями (Multi-application management, multi-DXE).

[Что такое процесс загрузки (Booting)]

Booting (загрузка) - это процесс копирования кода и данных приложения, которые хранятся во внешнем устройстве памяти (или на внешнем хостовом устройстве), в различные внутренние и внешние области памяти процессора Blackfin. После завершения загрузки процессор может начинать выполнять код приложения. Процесс загрузки обрабатывается специальным встроенным в процессор кодом Boot ROM (не перезаписываемый код, который размещен в адресном пространстве процессора Blackfin по адресам 0xEF000000 .. 0xEF0003FF). На рис. 1 показана последовательность операций от исходного кода приложения до запуска конечного двоичного кода в целевой рабочей системе.

EE 240 Blackfin stand alone system fig01

Рис. 1. Как запускается код приложения на процессорах ADSP-BF531/BF532/BF533.

Как только исполняемый файл (*.dxe) полностью отлажен и проверен, утилита загрузчика готова к преобразованию этого исполняемого файла в загружаемый процессором (boot-loadable) файл. Загружаемый файл может быть автоматически загружен (этот процесс называется boot) в процессор после включения питания и/или после программного или аппаратного сброса. Способ, каким утилита загрузки создает загружаемый файл, зависит от того, как загружаемый файл загружается в процессор (т. е. от выбранного разработчиком способа загрузки).

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

Режим загрузки (boot mode) процессора определяется (сразу после сброса) путем опроса одного или нескольких входных выводов. Последовательности загрузки сильно зависят от используемого процессора (подробнее см. аппаратное руководство по Вашему процессору и документ "VisualDSP 5.0 Loader and Utilities Manual").

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

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

[No-Boot Mode]

После сброса процессор начинает считывать и выполнять инструкции непосредственно из устройств памяти EPROM/flash. В энергонезависимой памяти находится сырой набор инструкций процессора, поэтому эта схема не требует специального механизма загрузки. Задача инициализации и использования энергозависимой памяти (обычно специальной инициализации перед использованием требует L3 SDRAM) ложится на программу пользователя.

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

[PROM Boot Mode]

После сброса процессор начинает читать данные из параллельного или последовательного устройства PROM. В памяти устройства PROM сохранен специальным образом сформированный поток загрузки (boot stream) вместо сырого кода инструкций. Помимо данных приложения, поток загрузки boot stream содержит дополнительные данные, такие как адреса назначения и количество слов в блоке (описание формата потока загрузки далее в этой статье). Маленькая программа, которая называется boot kernel (ядро загрузки, см. ниже) считывает и обрабатывает поток загрузки, и по находящимся там данным инициализирует (записывает) различные области памяти. Ядро загрузки работает на целевом процессоре, для которого загружается программа. В зависимости от архитектуры процессора, boot kernel может выполняться либо из встроенного в кристалл кода Boot ROM, либо может быть загружено в память L1 SRAM процессора из внешнего источника и затем запущено оттуда на выполнение.

Утилита загрузчика генерирует boot stream из исполняемого файла *.dxe, сгенерированного линкером, и сохраняет в выбранном формате, пригодном для прошивки в PROM.

В этой статье подробно рассматривается режим PROM Boot Mode для процессора ADSP-BF533. Другие процессоры ADSP-BF5xx имеют аналогичные режимы загрузки, незначительно отличаясь друг от друга в деталях.

[Host Boot Mode]

В этой схеме целевой процессор является подчиненным по отношению к системе хоста. Система хоста это другая интеллектуальная система (другой процессор, микроконтроллер или микросхема FPGA), которая управляет процессом загрузки. После сброса процессор сигнализирует хосту о готовности загрузить программу. Запуск программы откладывается до момента, когда процессор сигнализирует хосту, что программа полностью загружена. В зависимости от возможностей аппаратуры имеется 2 метода загрузки с хоста. В первом случае система хоста полностью управляет всей памятью целевой процессорной системы. Хост останавливает целевую систему, пока не будет проинициализирована вся память, как это необходимо (кстати, запуск сессии отладки через JTAG также может считаться таким случаем). Во втором случае в целевом процессоре работает ядро загрузки, и оно обменивается с хостом специальными сообщениями (boot handshake). Ядро загрузки (как и в PROM Boot Mode) может выполняться из Boot ROM кристалла процессора, либо может быть предварительно загружено хостом в память SRAM процессора по любой из доступных схем (bootstrapping).

Утилита загрузки/сплиттера [3] генерирует файл, который может использовать устройство хоста в процессе передачи данных загрузки. От возможностей хоста и архитектуры целевого процессора зависит, каким будет поток данных загрузки - либо сырые данные приложения, либо форматированный boot stream.

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

[Ядра загрузки]

Термин "ядро загрузки" (boot kernel) относится к резидентной программе (находящейся обычно в Boot ROM на кристалле процессора), которая отвечает за загрузку кода приложения для процессора. Альтернативно (в случае отсутствия Boot ROM) ядро загрузки может быть предварительно загружено и запущено по одной из доступных схем загрузки (bootstrapping).

Когда на процессор посылается сигнал сброса, процессор начинает загрузку из PROM, устройства хоста или через коммуникационный порт (например UART или CAN). К примеру, процессор ADSP-2106x/ADSP-2116x помещает для выполнения программу из 256 слов во внутреннюю память процессора. Эта маленькая программа и есть ядро загрузки.

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

Некоторые более новые процессоры Blackfin не требуют специальной загрузки для boot kernel, оно уже присутствует на кристалле процессора (это так называемое on-chip Boot ROM). Это позволяет всему телу приложения пользователя быть загруженным во внутреннюю или внешнюю память процессора. Ядро загрузки, находящееся на кристалле процессора, ведет себя подобно загрузчику второго уровня (second-stage loader) процессоров ADSP-BF535. Boot ROM может обработать информацию адреса и количества слов каждого загружаемого блока потока загрузки.

[Поток загрузки]

Утилита загрузки (loader utility) генерирует выходной файл (с расширением .ldr), загружая в него все то же самое, что находится в исполняемом входном файле (с расширением .dxe). Утилита загрузки просто переупаковывает исполняемый файл по схеме, показанной на рисунке.

VisualDSP DXE vs LDR file

В файле DXE находятся следующие данные:

• Инструкции DSP (код CODE и данные DATA).
• Таблица символов программы и информация о используемых секциях памяти.
• Распределение памяти целевого процессора.
• Отладочная информация (используется для отладки по исходному коду).

В файле LDR находятся следующие данные:

• Инструкции DSP (код CODE и данные DATA).
• Рудиментарная вспомогательная информация заголовков блоков (вся отладочная информация удалена).

Код процессора (CODE) и данные (DATA), находящиеся в файле загрузки (вся эта информация также называется потоком загрузки, boot stream) поделена на блоки. Каждый блок промаркирован заголовком, который содержит информацию о типе блока, адресе назначения и количеству слов в этом блоке. В зависимости от семейства процессора в заголовке может находиться разная дополнительная информация. Общепринятыми типами блоков являются "zero" (память, заполняемая нулями), nonzero (код или данные) и final (последний блок кода или данных), подробности см. в описании ниже. В зависимости от семейства процессора могут быть блоки других типов.

Примечание: в этом разделе приведены данные для процессоров Silicon Revision 0.3. Для более ранних ревизий см. приложение "Режимы загрузки и версии кристаллов".

Процессоры Blackfin могут загрузиться из flash/PROM асинхронной памяти Bank 0 (доступной через блок EBIU [2] или через устройство с интерфейсом SPI (это может быть микросхема памяти или активный хост). В таблице 1 перечислены режимы загрузки процессоров ADSP-BF531/BF532/BF533, которые выбираются уровнями внешних выводов корпуса BMODE[1:0] в момент перехода завершения сброса (когда сигнал RESET переходит в неактивный уровень).

Таблица 1. Режимы загрузки ADSP-BF531/BF532/BF533.

BMODE[1:0] Описание (также см. раздел "Описание специфики режимов загрузки Blackfin ")
00 Выполнение из внешней 16-битной памяти, подключенной к ASYNC Bank0 (пропуск запуска кода Boot ROM).
01 Загрузка из 8/16 битной параллельной микросхемы FLASH/PROM.
10 Загрузка через SPI в режиме SPI Slave mode (данные поступают от хоста SPI).
11 Загрузка из памяти SPI, адресуемой 8/16/24 битами, с поддержкой микросхем памяти Atmel AT45DB041B, AT45DB081B и AT45DB161B DataFlash® (хостом SPI выступает загружаемый процессор Blackfin).

Как показано на рис. 1, утилита создания образа для загрузчика [3] (loader utility, elfloader.exe, находится в корневом каталоге VisualDSP, обычно это %ProgramFiles%\Analog Devices\VisualDSP 5.0\) обрабатывает входной исполняемый файл (.DXE) и создает в результате файл загрузки (loader file, файл с расширением .LDR), состоящий из блоков данных, каждому из которых предшествует заголовок. Этот файл загрузки затем программируется/прошивается во внешнюю память/устройство (или передается хосту). Заголовки впоследствии будут прочитаны и обработаны встроенным кодом Boot ROM во время процедуры загрузки.

Примечание: по ключам файлов загрузки обратитесь к руководству [3].

Чтобы получить краткую подсказку по основным опциям, можно запустить elfloader.exe без указания опций. Однако в такой подсказке указаны не все опции, поэтому все-таки полное руководство по опциям elfloader следует смотреть в документации [3]. Здесь приведен краткий обзор основных используемых опций.

Примечание: среда разработки VisualDSP++ для генерации файла загрузки *.ldr использует запуск утилиты elfloader.exe, и командную строку запуска можно посмотреть в лог-файле имя_проекта.log (он находится в выходном каталоге проекта Release).

Вот пример вызова утилиты elfloader.exe, разберем его опции командной строки:

elfloader.exe .\Release\mainprog.dxe -b Flash -f BINARY -Width 16 -init .\boot\Release\Init_Sdram.dxe
 -o .\Release\myproj.ldr -si-revision 0.5 -proc ADSP-BF538 -MM

Сразу за именем утилиты elfloader идет путь до исполняемого файла основной программы mainprog.dxe, за ним идут различные опции. В этом примере в качестве входного файла *.dxe указан только один файл mainprog.dxe, однако можно указать несколько файлов *.dxe друг за другом через пробел, все они попадут в выходной файл, в отдельные секции DXE (так называемая множественная загрузка, Multi-.dxe Boot). Ниже рассмотрены основные опции командной строки утилиты elfloader.exe.

-b < тип_памяти >

Эта опция указывает, из какой памяти будет происходить загрузка файла *.ldr. Возможные параметры опции: prom, flash, spi, spislave, UART, TWI, FIFO.

-f < формат_загружаемого_файла >

Указывает формат выходного генерируемого файла. Возможные значения: hex, ASCII, binary, include.

-Width < N >

Эта опция указывает в параметре N ширину шины данных микросхемы памяти, в которой сохранен образ загрузки (файл *.ldr). Например, если для хранилища файла загрузки используется встроенная в кристалл память FLASH процессора ADSP-BF538F, то следует указать в качестве N значение 16.

-init < DXE_для_Init_Code >

Эта опция указывает исполняемый файл для кода инициализации (так называемый Init Code).

-proc < модель_процессора >

Это обязательная опция, указывающая модель процессора.

-o < выходной_файл >

Указывает имя выходного генерируемого файла загрузки.

-si-revision < ревизия_кристалла >

Указывает ревизию процессора. От этого зависит формат выходного файла и поддерживаемые режимы загрузки.

-MM

Задает генерацию выходного файла в соответствии с зависимостями make, что определяет формирование выходного файла *.ldr.

EE 240 Blackfin boot process fig02

Рис. 2. Процесс загрузки ADSP-BF531/BF532/BF533.

Загрузка в память scratchpad (0xFFB00000 .. 0xFFB00FFF) не поддерживается. Если делается попытка загрузки в память scratchpad, то процессор зависнет на выполнении кода Boot ROM.

[Информация заголовка]

Как показано на рис. 3, каждый 10-байтный заголовок в файле загрузки состоит из 4-байтного поля ADDRESS, 4-байтного поля COUNT и 2-байтного поля FLAG.

EE 240 10 Byte Header Contents fig03

Рис. 3. Содержимое 10-байтного заголовка.

Во время загрузки код Boot ROM обрабатывает поля этого 10-байтного заголовка следующим образом:

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

EE 240 Control Bits FLAG fig04

Рис. 4. Отдельные биты управления поля FLAG заголовка.

Описание битов поля FLAG:

Бит 0: ZEROFILL - показывает, что этот блок должен быть заполнен нулями. Блоки ZEROFILL не имеют полезной нагрузки в файле загрузки (т. е. будет присутствовать только заголовок). Они просто инструктируют код Boot ROM заполнить нулями память COUNT байт, начиная с адреса ADDRESS. Это дает значительное уменьшение файла загрузки для приложений, у которых есть большие буферы данных, заполненные нулями. Это также очень полезно для ANSI-C совместимых проектов ANSI-C, в которых часто нужно заполнить нулями большие буферы при запуске программы.

Бит 1: RESVECT – показывают вектор сброса после загрузки, благодаря чему все кристаллы ADSP-BF531/BF532/BF533 используют одинаковый код Boot ROM. Этот бит устанавливается в 0 для ADSP-BF531/BF532 и устанавливается в 1 для ADSP-BF533. После завершения загрузки Boot ROM использует этот бит для перехода по адресу 0xFFA00000 для ADSP-BF533 или по адресу 0xFFA0 8000 для ADSPBF531/BF532.

После аппаратного сброса вектор сброса (хранящийся в регистре EVT1) установлен в 0xFFA00000 или 0xFFA08000, в зависимости от бита RESVECT. Если установлен бит 4 (No Boot on Software Reset, пропустить загрузку при программном сбросе) в регистре SYSCR, и выдан программный сброс, то процессор произведет переход по адресу вектора, установленному в регистре EVT1. Этот вектор сброса может быть переконфигурирован на другой адрес во время выполнения программы. Так что приложение может запрограммировать переход на другой, отличающийся от 0xFFA00000 или 0xFFA08000 (переход после выполнения программного сброса). Если вектор сброса изменен во время выполнения программы, то убедитесь, что вектор сброса в регистре EVT1 содержит адрес допустимой инструкции. Этот адрес может быть адресом внутренней памяти инструкций, памяти SDRAM, или асинхронной памяти (например FLASH). У регистра EVT1 нет никакого значения по умолчанию. Значение в этом регистре будет сохранено после выдачи сброса. Когда BMODE = 00, код Boot ROM пропускается, и Вы должны инициализировать регистр EVT1 перед выдачей программного сброса.

Бит 3: INIT – блок инициализации (Init Block), блок кода, который выполняется перед тем, как поверх него загрузится код реального рабочего приложения. Когда код Boot ROM определит наличие Init Block, он загружает его во внутреннюю память, и делает его вызов как подпрограммы инструкцией CALL (код инициализации должен иметь в конце инструкцию RTS). После того, как код инициализации выполнен, он обычно перезаписывается кодом приложения, см. рис. 5.

Бит 4: IGNORE – показывает блок, который не записывается в память. В этом месте дается указание для кода Boot ROM пропустить COUNT из файла загрузки. В режиме загрузки из микросхемы памяти код Boot ROM может просто модифицировать исходный указатель адреса. В режиме загрузки под управлением хоста код Boot ROM должен активно отбрасывать приходящие данные. Текущий инструментарий VisualDSP++® поддерживает блоки IGNORE только для глобальных заголовков - в настоящий момент 4-байтный DXE Count, см. ниже раздел "Управление несколькими приложениями (Multi-application management, multi-DXE)".

Биты 8:5: PFLAG - эти биты используются для SPI Slave mode boot (BMODE = 10), т. е. загрузка под управлением внешнего хоста. PFLAG показывает номер вывода порта PFx, используемого под сигнал приостановки хоста (host wait, HWAIT) от процессора Blackfin, на который должен реагировать хост Master SPI. Это значение может быть в диапазоне 1..15 (0x1..0xF) для процессоров ADSP-BF531/BF532/BF533. За дополнительной информацией по использованию этого строба PF обратитесь к разделу "Загрузка от хоста - мастера SPI" (BMODE = 10).

Бит 15: FINAL – показывает, что после этого блока процесс загрузки завершен. После обработки блока FINAL код Boot ROM делает переход по адресу вектора, который хранится в регистре EVT1. Процессор все еще находится в режиме супервизора (Supervisor mode, см. [4]) и на самом низком уровне приоритета прерывания (IVG15), когда он переходит к выполнению кода из памяти L1.

В отличие от процессоров ADSP-BF535, процессоры ADSP-BF531/BF532/BF533 не требуют загрузчика второй стадии. Поле FLAG в 10-байтном заголовке предоставляет для процессоров ADSP-BF531/BF532/BF533 всю необходимую информацию для выполнения последовательности загрузки в одной стадии, без необходимости наличия второй стадии загрузки.

[Код инициализации (Init Code)]

Init Code это фича, которая позволяет выполниться кусочку кода перед тем, как будет загружено реальное приложение. Init Code код может выполнять разные функции, включая инициализацию контроллера SDRAM, изменение настройки PLL, скорость работы SPI, или количество циклов ожидания (wait states) блока EBIU для ускорения загрузки, и т. д.. Init Code может быть добавлен в начала файла загрузки с помощью командной строки "elfloader –Init Init_Code.DXE", где Init_Code.DXE указывает на предоставленный пользователем выполняемый код инициализации.

EE 240 Initi Code Execution Boot fig05

Рис. 5. Выполнение Init Code при загрузке.

Когда код Boot ROM детектирует блок с установленным битом INIT, то он сначала загружает этот код в память Blackfin и выполняет его как подпрограмму путем выдачи CALL на целевой адрес блока INIT. По этой причине Вы должны завершить Init Code инструкцией RTS, чтобы гарантировать, что процессор перейдет обратно в код Boot ROM для завершения процесса загрузки.

Программист должен сохранить на входе Init Code и восстановить при выходе все регистры, которые были использованы и модифицированы. Рекомендуется как минимум, чтобы каждый Init Code сохранял ASTAT, RETS и все регистры Rx и Px. Процессор Blackfin предоставляет достаточный объем стека в памяти scratchpad (0xFFB00000 .. 0xFFB00FFF). Init Code может выполнить операции push и pop на текущем указателе стека (stack pointer) SP. Листинг 1 показывает пример Init Code, который демонстрирует настройку контроллера SDRAM [5].

#include < defBF532.h >
.section program;
/********************************************************************/
   [--SP] = ASTAT; // сохранение регистров в стеке
   [--SP] = RETS;
   [--SP] = (R7:0);
   [--SP] = (P5:0);
/********************************************************************/
/*******Init Code Section********************************************/
/*******SDRAM Setup************/
Setup_SDRAM:
   P0.L = lo(EBIU_SDRRC);
   P0.H = hi(EBIU_SDRRC); // SDRAM Refresh Rate Control Register
   R0 = 0x074A(Z);
   W[P0] = R0;
   SSYNC;
   P0.L = lo(EBIU_SDBCTL);
   P0.H = hi(EBIU_SDBCTL); // SDRAM Memory Bank Control Register
   R0 = 0x0001(Z);
   W[P0] = R0;
   SSYNC;
   P0.L = lo(EBIU_SDGCTL);
   P0.H = hi(EBIU_SDGCTL); // SDRAM Memory Global Control Register
   R0.H = 0x0091;
   R0.L = 0x998D;
   [P0] = R0;
   SSYNC;
/********************************************************************/
   (P5:0) = [SP++]; // восстановление регистров из стека
   (R7:0) = [SP++];
   RETS = [SP++];
   ASTAT = [SP++];
/********************************************************************/
   RTS;

Листинг 1. Пример Init Code.

Обычно Init Code содержит одну секцию, и представляет один блок в потоке загрузки (т. е. в данных файла загрузки). В этом блоке, само собой, установлен бит INIT. Тем не менее, блок Init может также состоять из нескольких секций. Таким образом, в потоке загрузки может быть несколько блоков Init Code, и только в последнем блоке из них установлен бит INIT. Утилита elfloader гарантирует, что последний из этих блоков перенаправит выполнение процессора на точку входа Init Code. Если это сложно для elfloader, то он сохраняет бит INIT очищенным для последнего блока и выдает после него один дополнительный блок. В этом дополнительном блоке установлен бит INIT, но не предоставлено полезной нагрузки (COUNT = 0). Он всего лишь инструктирует код Boot ROM выполнить инструкцию CALL с переходом на подпрограмму по указанному адресу ADDRESS.

Хотя исполняемые файлы Init Code (файлы .DXE) собираются через свои отдельные проекты VisualDSP++, они отличаются от стандартных проектов. Проекты Init Code предоставляют только вызываемую подпрограмму, так что они больше похожи на библиотеку, чем на приложение. Init Code всегда предшествует обычному коду приложения. Следовательно вне зависимости от того, состоит ли Init Code из одного или из нескольких блоков, он никогда не завершается установленным индикатором бита FINAL, который будет установлен только в момент завершения кодом Boot ROM процесса загрузки.

[Управление несколькими приложениями (Multi-application management, multi-DXE)]

В дополнение к предварительной инициализации при загрузке, фича Init Code также может использоваться для управления загрузкой. Файл загрузки (.LDR) может хранить в себе несколько приложений, если в командной строке elfloader перечислено несколько исполняемых файлов (.DXE). Утилита elfloader создает несколько потоков загрузки с индивидуальными выполняемыми блоками, добавленными друг за другом, где Init Code DXE размещен в самом начале (см. рис. 6).

EE 240 Multi DXE Loader File fig06

Рис. 6. Содержимое файла Multi-DXE Loader.

Структура файла загрузки (.LDR) ADSP-BF531/BF532/BF533 позволяет Вам определить границу между выполняемыми блоками (приложениями DXE), сохраненными во внешней памяти, так что есть возможность загрузить специфичное приложение DXE. Каждый файл .DXE обрабатывается и размещается в файле .LDR с заголовком, где установлен бит IGNORE. В настоящий момент этот блок IGNORE содержит значение 4-байтного счетчика, равный количеству байт, содержащемуся в приложении, включая заголовок. Другими словами, это смещение на следующее приложение DXE. В будущем блок IGNORE может использоваться для хранения информации в дополнение к 4-байтному значению счетчика. Имейте в виду, что каждый блок IGNORE имеет заголовок из 10 байт.

С этой информацией счетчика DXE пользователь может "перепрыгнуть" через все приложения DXE в файле .LDR, пока не встретит приложение DXE, выбранное для загрузки. В листинге 2 показан кусок Init Code, который демонстрирует, как продвигаться через несколько приложений DXE из 8-битной FLASH. Предполагается, что файл .LDR содержит один Init Code DXE и два приложения DXE, Init Code проскакивает через файл .LDR для загрузки второго приложения DXE.

[Загрузка от хоста - мастера SPI]

#include < defbf533.h >
.section program;
   [--SP] = ASTAT;   // сохранение регистров в стек
   [--SP] = RETS;
   [--SP] = (r7:0);
   [--SP] = (p5:0);
   [--SP] = LC0;
   [--SP] = LT0;
   [--SP] = LB0;
/******************************/
BOOT_DXE:
   R0.H = 0x2000;    // R0 = начало ASYNC Bank 0
   R0.L = 0x0000;
   P1 = 2;           // Количество DXE, которые проматываются (не должно быть 0!!)
                     // После первой итерации R0 будет указывать на DXE1.
                     // После второй итерации R0 будет указывать на DXE2.
   LSETUP(ADD_DXE_COUNT_BEGIN, ADD_DXE_COUNT_END) LC0 = P1;
ADD_DXE_COUNT_BEGIN:
   R1 = 0xA;         // Пропуск 10 байт 1-го заголовка
   R1 = R1 << 1;     // Умножение на 2, поскольку мы загружаемся из 16-битной
                     //  flash (компенсация дополнения нулями)
   R0 = R0 + R1;
   P0 = R0;          // P0 указывает на 4-байтный DXE COUNT
   R0 = W[P0++](Z);  // R0 = xx | биты[7:0] DXE COUNT
   R1 = W[P0++](Z);  // R1 = xx | биты[15:8] DXE COUNT
   R1 = R1 << 8;
   R2 = W[P0++](Z);  // R2 = xx | биты[23:16] DXE COUNT
   R2 = R2 << 16;
   R3 = W[P0++](Z);  // R3 = xx | биты[31:24] DXE COUNT
   R3 = R3 << 24;
   R0 = R0 | R1;     // R0 = биты[15:0] DXE COUNT
   R2 = R2 | R3;     // R2 = биты[31:16] DXE COUNT
   R3 = R0 | R2;     // R3 = DXE COUNT
   R0 = P0;
   R0 = R0 + R3;     // Модификация указателя R0 на DXE COUNT байт
   P0 = R0;          // к следующему DXE
ADD_DXE_COUNT_END:
   NOP;
/******************************/
DONE:
   LB0 = [SP++];     // Восстановление регистров
   LT0 = [SP++];
   LC0 = [SP++];
   (p5:0) = [SP++];
   (r7:1) = [SP++];  // ----- > R0 НЕ ВОССТАНАВЛИВАЕТСЯ < -------
   RETS = [SP++];    // Модификация SP на 1 в случае R0
   RETS = [SP++];    // Выталкивание реального значения RETS
   ASTAT = [SP++];
   RTS;

Листинг 2. Пример Init Code для Multi-DXE Boot.

Обратите внимание, что регистр R0 не восстанавливается по окончании Init Code, потому что R0 это внешний указатель для flash/PROM boot (BMODE = 01). Когда процессор вернулся обратно в код Boot ROM после инструкции RTS, код Boot ROM продолжит загрузку из места, сохраненного в R0. Подобным образом, если режим загрузки выбран для загрузки через SPI (BMODE = 11), внешний указатель сохраняется в R3. Таким образом, для загрузки через SPI не восстанавливайте R3 внутри Init Code для окружения загрузки multi-DXE.

Имеется прилагаемый к этому даташиту пример загрузки multi-DXE (BF533 Ez Kit Multiple DXE Boot.zip [2]), который использует плату разработчика ADSP-BF533 EZ-KIT Lite®. ZIP-файл содержит 2 проекта, мигающие светодиодами, и проект Init Code. При RESET, встроенный в процессор код Boot ROM загрузит Init Code. Затем Init Code будет ждать, пока не будут выставлены сигналы на PF8 (кнопка SW4) или PF9 (кнопка SW5). Если выставлен PF8, то будет загружен и выполнен DXE1, если PF9, то DXE2. DXE1 мигает светодиодами платы по очереди, а DXE2 мигает всеми светодиодами платы одновременно.

[Описание специфики режимов загрузки Blackfin]

После того, как мы получили общее представление о процессе загрузки для процессоров ADSP-BF531, ADSP-BF532 и ADSP-BF533, в остальной части этой статьи будут рассмотрены особенности работы каждого режима загрузки, такие как аппаратный интерфейс, структура файла загрузки и ожидаемое поведение выводов. Выполнение из внешней 16-разрядной памяти (BMODE = 00) обсуждается из даташита EE-239 [6].

В следующих секциях будет использоваться пример мигания светодиодами на ассемблере для ADSP-BF533 EZ-KIT Lite board вместе с Init Code.

Обратите внимание, что каждый из перечисленных здесь режимов загрузки адресует область 0xFF807FF0 .. 0xFF807FFF (последние 16 байт L1 Data Bank A) так что эта область должна быть зарезервирована. Этот диапазон ячеек памяти использует код Boot для хранения информации заголовка каждого блока в файле загрузки. После завершения загрузки этот диапазон памяти может использоваться приложением во время выполнения своего кода. См. приложение для ревизий кристалла (silicon revisions) 0.1 и 0.2.

8-Bit Flash/PROM Boot (BMODE = 01). Поскольку блок EBIU процессора Blackfin 16-разрядный (так что нет разряда адреса ADDR[0]), 8-битные flash/PROM будут занимать только младшие 8 разрядов шины данных (D[7:0]). На рис. 7 показано соединение выводов между процессором Blackfin и 8-разрядной микросхемой flash/PROM.

EE 240 conn 8bit FLASH fig07

Рис. 7. Соединения шин адреса, данных и управляющих сигналов между Blackfin и 8-битной микросхемой Flash/PROM.

Листинг 3 показывает файл загрузчика, созданный для 8-разрядной flash/PROM в формате Intel hex [7] (см. архив с примерами [2]). Он разделен на разные секции, чтобы показать структуру файла загрузки.

EE 240 Example Intel Hex Loader File

 

Листинг 3. Пример Intel Hex Loader File для процессора Blackfin.

Файл загрузки в листинге 3 собран для silicon revision 0.3. Файлы загрузки, собранные для silicon revision 0.2 и ниже имеют несколько отличающуюся структуру.

Когда этот файл загрузки записан в 8-разрядную микросхему FLASH, подключенную к ASYNC Bank 0 процессора Blackfin, содержимое памяти (начиная с адреса 0x20000000) будет выглядеть с точки зрения Blackfin как показано на рис. 8.

EE 240 8 Bit Flash PROM fig08

Рис. 8. Содержимое памяти подключенной 8-разрядной микросхемы Flash/PROM, как его видит процессор Blackfin.

На рис. 9 показано начало последовательности загрузки для 8-разрядной flash/PROM.

EE 240 Timing Diagram 8 Bit Flash Boot fig09

Рис. 9. Диаграммы сигналов при загрузке из 8-битной микросхемы FLASH.

16-Bit Flash/PROM Boot (BMODE = 01). На рис. 10 показаны соединения между процессором Blackfin и 16-разрядной микросхемой flash/PROM.

EE 240 conn 16bit FLASH fig10

Рис. 10. Соединения шин адреса, данных и управляющих сигналов между Blackfin и 16-битной микросхемой Flash/PROM.

Если мы создали файл загрузки для 16-битной микросхемы flash/PROM для примера [2], то он будет таким же, как показано в листинге Listing 3, за исключением того, что поле ADDRESS в 10-байтном заголовке для DXE для счетчика блоков будет 0xFF800060 вместо 0xFF800040 для 8-битной микросхемы flash/PROM. Это приведет к тому, что первый байт файла загрузки будет равен 0x60 вместо 0x40. Встроенный в процессор код Boot ROM использует этот байт для того, чтобы определить, какая подключена микросхема 8-разрядная или 16-разрядная flash/PROM. Если 1 байт равен 0x60, то это означает, что подключена 16-битная микросхема flash/PROM; если же 1 байт равен 0x40, то значит подключена 8-разрядная flash/PROM.

Когда этот файл загрузки записан в 16-разрядную микросхему FLASH, подключенную как ASYNC Bank 0 процессора Blackfin, содержимое памяти (начиная с адреса 0x20000000) процессор будет видеть так, как показано на рис. 11.

EE 240 16 Bit Flash PROM fig11

Рис. 11. Содержимое памяти подключенной 16-разрядной микросхемы Flash/PROM, как его видит процессор Blackfin.

Структура файла загрузки на рис. 11 для 16-битной микросхемы flash/PROM предоставлена только для silicon revision 0.3 и выше. Silicon revision 0.2 и ниже процессоров ADSP-BF531/BF532/BF533 поддерживают загрузку только из 8-битных микросхем. Таким образом, если выбрана ширина шины 16 бит для silicon revision 0.2 и ниже, выходной файл загрузки должен быть дополнен нулевыми байтами, чтобы симулировать 8-битные данные загрузки в 16-битной микросхеме flash/PROM. Этот файл загрузки, когда он записан в память flash/PROM, будет выглядеть как на рис. 8, но с заполненными нулями старших 8 битах (DATA[15:8]) шины данных.

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

EE 240 Timing Diagram 16 Bit Flash Boot fig12

Рис. 12. Диаграммы сигналов при загрузке из 16-битной микросхемы FLASH.

Процессор будет выполнять начальное чтения ячейки 0x0 памяти flash, чтобы определить ширину шины памяти flash. Когда происходит загрузка из FIFO, первый байт (который является частью первого 10-байтного заголовка в файле загрузки) должен быть послан дважды: один раз для этого начального чтения, и еще один раз для реальной последовательности загрузки.

SPI Slave Mode Boot под управлением мастер-хоста (BMODE = 10). В этом режиме процессор ADSP-BF531/BF532/BF533 сконфигурирован как подчиненное устройство SPI, в которое передает данные загрузки какой-то внешний процессор (мастер-хост).

Этот режим загрузки не поддерживается в процессорах ADSPBF531/BF532/BF533 silicon revision 0.2 и ниже.

На рис. 13 показаны соединения для этого режима. Хосту ничего не нужно знать о структуре потока данных файла загрузки, который он передает процессору Blackfin. Хост должен быть сконфигурирован так, чтобы посылать по одному байту за 1 раз из имеющегося файла загрузки (формат ASCII). В такой схеме одна из ножек PFx процессора Blackfin должна использоваться выход сигнала ожидания для хоста (host wait, HWAIT), подаваемого от процессора Blackfin к мастер-хосту. Это будет сигнализировать хосту, когда он должен приостановиться на некоторое время в течение процессора загрузки, чтобы ожидать готовности процессора Blackfin принять данные (особенно для ожидания завершения выполнения Init Code и обработки блоков zero-fill). Когда PFx выставлен (лог. 1), то мастер-хост должен приостановить отправку байтов процессору Blackfin. Когда сигнал на PFx снят (лог. 0), мастер-хост возобновит отправку оставшихся байтов. Так как вывод PFx не управляется процессором Blackfin при обработке 1 блока, то нужно использовать нижний подтягивающий резистор (pull down) для сигнала HWAIT (см. рис. 13).

EE 240 conn SPI FLASH slave mode fig13

Рис. 13. Соединения между мастер-хостом DPI и подчиненным загружаемым процессором Blackfin.

Перед отправкой каких-либо байт хост должен гарантировать, что процессор Blackfin вышел из состояния сброса. Все байты, отправленные до выхода процессора Blackfin из сброса, будут потеряны и процесс загрузки завершится неудачно.

Номер вывода PFx задается пользователем, и эта информация будет встроена в файл загрузки. Утилита elfloader запишет этот номер в поле PFLAG (биты [8:5] слова FLAG) внутри каждого 10-байтного заголовка. Номер PFx указывается в опции –pflag number командной строки, где параметр number предназначен для выбора номера PFx, используемого подчиненным устройством Blackfin, и его значение может быть в диапазоне от 1 до 15.

Если опция –pflag number опущена, то значение по умолчанию, которое будет помещено в биты 8:5 слова FLAG, будет 0, что задаст использование PF0 для сигнала HWAIT. Поскольку сигнал PF0 мультиплексирован с выводом /SPISS, который нужен для правильной загрузки через SPI, всегда используйте опцию –pflag и указывайте в ней любое значение, отличающееся от 0.

Из-за наличия ошибки (anomaly) Rev 0.3 Boot Rom, после завершения загрузки регистры SPI Control и конфигурации DMA5 не будут иметь свои значения по умолчанию.

На системах, где на Blackfin работает в подчиненном режиме загрузки была протестирована максимальная скорость SPI мастер-хоста 1 МГц, при этом у подчиненного процессора Blackfin была тактовая частота CCLK = 333 МГц, SCLK = 66.6 МГц.

В примерах, относящихся к этой статье, есть пример кода для хоста (Host_Code.zip [2]) для случая, когда процессор ADSP-BF532 используется в качестве хоста загрузки.

Ниже приведены диаграммы времени SPI Slave mode boot с использованием процессора ADSP-BF532 в качестве хоста, и процессора ADSP-BF533 в качестве подчиненного устройства SPI. Со стороны хоста ножка порта PF4 используется для сигнала /CS, который подключен к /SPISS подчиненного ADSP-BF533. Порт PF13 для подчиненного SPI (процессор ADSP-BF533) подключен к порту PF15 хоста SPI (процессор ADSP-BF532). Это соединение работает для передачи сигнала HWAIT, чтобы иметь возможность приостановки хоста. Все диаграммы времени на рисунках показаны со стороны подчиненного устройства SPI (процессор ADSP-BF533, который находится в режиме загрузки).

Используемый файл загрузки (SPI_Slave_HostFile.ldr) тот же самый, который был показан в листинге 3, за исключением 2 дополнительных блоков, которые были добавлены, чтобы показать функциональность этого режима загрузки: блок с заполнением нулями (zero-fill block), помещаемый с адреса 0xFFA00300 размером в 0x4000 байт, и блок данных, помещаемый с адреса 0xFFA04300, который содержит следующие значения: 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF и 0x19.

Рис. 14 показывает полную последовательность загрузки SPI Slave mode boot.

EE 240 Timing Diagram SPI Slave Mode Boot fig14

Рис. 14. Диаграммы времени для последовательности загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI.

После того, как подчиненное устройство SPI slave примет первые 10 байт заголовка от хоста, оно будет знать, какой вывод порта PFx использовать в качестве сигнала HWAIT. В этом случае был использован PF13. Обратите внимание на снятие сигнала PF13 на рис. 15 после того, как были обработаны биты 8:5 поля FLAG.

В целях отладки рис. 15 был захвачен с использованием верхнего подтягивающего резистора (pull-up) на PF13. Для нормальной работы рекомендуется применить нижний подтягивающий резистор pull-down, тогда PF13 будет все время в лог. 0.

EE 240 SPI Slave Mode Boot fig15

Рис. 15. Диаграммы времени начала последовательности загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI.

После того, как хост отправит 4-байта блока Init Code DXE Count, он пошлет 10 байт заголовка Block 1 Init Code DXE, и затем само содержимое Block 1.

EE 240 SPI Slave Mode Boot Sequence Block1 Init Code DXE fig16

Рис. 16. Диаграммы времени загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI:передача Boot Block 1 для Init Code DXE.

После того, как весь Init Code DXE загружен в память подчиненного устройства SPI Blackfin, он выставит сигнал HWAIT на порте PF13, что покажет хосту, чтобы он больше не отправлял данные, пока выполняется Init Code. Поскольку ядро Blackfin работает намного быстрее, чем интерфейс SPI, код Init Code будет выполнен намного быстрее, чем передаются байты от хоста.

EE 240 SPI Slave Mode Boot Sequence Block2 Init Code DXE fig17

Рис. 17. Диаграммы времени загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI: передача Boot Block 2 для Init Code DXE.

На рис. 18 показана обработка блока zero-fill для этого режима загрузки. Когда код Boot ROM обнаруживает zero-fill block, он выставляет HWAIT PF13 чтобы хост приостановил отправку данных. В это время MDMA заполнит нулями 0x4000 байт в ячейках памяти 0xFFA00300 .. 0xFFA04300. Когда заполнение завершится, код Boot ROM снимет сигнал HWAIT, и хост продолжит посылать остальные байты процесса загрузки (10 байт заголовка для Block 3 и далее сами данные Block 3).

EE 240 SPI Slave Mode Boot Sequence Zero Fill Block fig18

Рис. 18. Диаграммы времени загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI: передача Zero-Fill Block (Block 2 для DXE1).

EE 240 SPI Slave Mode Boot Sequence Block3 DXE1 fig19

Рис. 19. Диаграммы времени загрузки в режиме, когда Blackfin работает как подчиненное устройство SPI: передача Boot Block 3 для DXE1 (последний блок).

Режим мастера при загрузки из памяти SPI (BMODE = 11). Для этого режима процессор ADSP-BF531/BF532/BF533 конфигурируется как мастер шины SPI, и через неё он подключен к памяти SPI, где хранится файл загрузки. На следующем рисунке показаны соединения, необходимые для этого режима.

EE 240 SPI Master Mode Boot conn fig20

Рис. 20. Соединение между процессором Blackfin и внешней микросхемой памяти SPI в режиме SPI Master Mode Boot.

Чтобы SPI Master Mode Boot работал правильно, нужен верхний подтягивающий резистор (pull-up) на сигнале MISO. По этой причине процессор ADSP-BF531/BF532/BF533 читает 0xFF на выводе MISO, если память SPI не отвечает (например, когда не передаются данные на вывод MISO от памяти SPI).

Хотя pull-up резистор на сигнале MISO обязателен, стило бы также применить дополнительные подтягивающие резисторы: 1) верхний подтягивающий резистор для PF2, чтобы гарантировать неактивность памяти SPI во время, когда процессор находится в состоянии сброса. 2) нижний подтягивающий резистор на сигнале SPICLK, установленный с целью получить более чистый сигнал тактов SPI.

На ревизиях кристалла (silicon revision) 0.2 и ниже биты CPHA и CPOL в регистре управления SPI (SPI Control, SPICTL) оба были установлены в 1 (см. [9] для дополнительной информации по этим битам). По этой причине память SPI может детектировать ошибочный фронт на сигнале тактов, когда он восстанавливается из третьего состояния. Если процесс загрузки терпит неудачу в такой ситуации, то верхний подтягивающий резистор на сигнале SPICLK позволит смягчить проблему. На кристалле silicon revision 0.3 это было исправлено установкой CPHA = CPOL = 0 в регистре управления SPI (SPICTL). Silicon revision 0.3 работает надежно и с pull-up резистором на SPICLK. Таким образом платы, которые поставляются с разными ревизиями кристалла, могут безопасно иметь верхний нагрузочный резистор на сигнале SPICLK. Однако Вы можете заметить на осциллографе, что на silicon revision 0.3 сигнал SPICLK неожиданно становится в уровень лог. 1, когда сигнал PF2 снят.

Микросхемы памяти SPI, поддерживаемые этим интерфейсом - стандартные, адресуемые по системе 8/16/24 бита микросхемы flash SPI (последовательность их чтения разъясняется далее), а также следующие микросхемы Atmel SPI DataFlash: AT45DB041B, AT45DB081B, AT45DB161B.

Примечание: в примере кода [2], поставляемом вместе с этим EE-Note, есть код примера, который программирует устройства памяти Atmel DataFlash с помощью процессора ADSP-BF532 Blackfin (см. Program_Atmel.zip [2]).

Стандартные микросхемы памяти с адресацией 8/16/24 бита это такие микросхемы, которые берут команду чтения байта 0x03, за которой идет 1 байт адреса (для 8-битно адресуемых микросхем памяти SPI), 2 байта адреса (для 16-битно адресуемых микросхем памяти SPI) или 3 байта адреса (для 24-битно адресуемых микросхем памяти SPI). После корректно отправленной команды чтения и отправленного адреса на вывод MISO будут последовательно выдвигаться данные из памяти, сохраненные в ней по указанному адресу. Данные отправляются последовательно от этого адреса согласно продолжающимися тактовыми импульсами SPI. Компания Analog Devices протестировала следующие стандартные микросхемы памяти SPI.

• 8-битно адресуемая память SPI: 25LC040 от Microchip
• 16-битно адресуемая память SPI: 25LC640 от Microchip
• 24-битно адресуемая память SPI: M25P80 от STMicroelectronics

[Как работает подпрограмма детектирования типа памяти SPI]

Поскольку BMODE = 11 поддерживает загрузку из различных микросхем памяти SPI, то код Boot ROM будет детектировать, какой тип памяти подключен к процессору. Чтобы определить тип памяти (адресуемая по 8, 16 или 24 разрядам), подключенной к процессору, встроенный код Boot ROM отправляет последовательность байт к микросхеме памяти SPI, отслеживая при этом, как микросхема памяти отвечает. Память SPI не будет отвечать, пока она не адресована должным образом. Итак, код Boot ROM делает следующее.

1. Отправляет команду чтения 0x03 через сигнал MOSI, затем делает пустые чтения через сигнал MISO.

2. Отправляет байт адреса 0x00 через сигнал MOSI, затем делает пустое чтение через сигнал MISO.

3. Отправляет другой байт 0x00 через сигнал MOSI и проверяет, является ли поступающий через MISO байт чем-то отличающимся от 0xFF (это данные, которые поступают от верхнего нагрузочного резистора). Пришедший байт со значением не 0xFF означает, что память SPI ответила после одного из байта адреса, и это означает, что подключена память SPI, адресуемая по 8 битам.

4. Если пришедший байт 0xFF, то код Boot посылает другой байт 0x00 через MOSI, и проверяет, какой на этот раз пришел байт, равен ли он 0xFF. Если пришедший байт не равен 0xFF, то это значит, что память ответила после 2 байт адреса, и следовательно это память SPI с адресацией по 16 битам.

5. Если поступивший байт 0xFF, то код Boot ROM посылает следующий байт 0x00, и проверяет, какой байт пришел на этот раз, равен ли он 0xFF. Если пришедший байт не равен 0xFF, то это означает, что что память ответила после 3 байт адреса, и следовательно это память SPI с адресацией по 24 битам.

6. Если пришедший байт все еще 0xFF (это значит, что никакое устройство памяти не ответило), то код Boot ROM предполагает, что возможно подключено одно из следующих устройств Atmel DataFlash: AT45DB041B, AT45DB081B или AT45DB161B. Эти устройства DataFlash имеют другую последовательность чтения, чем была описана раньше для стандартных микросхем памяти SPI. Если Вам нужно больше информации, то обратитесь к соответствующим даташитам на эти микросхемы. Код Boot ROM определяет, какая из микросхем Atmel DataFlash подключена, путем чтения регистра состояния. Главное отличие перечисленных устройств DataFlash - количество байт на странице памяти. AT45DB041B и AT45DB081B имеют 264 байта на страницу, а AT45DB161B имеют 528 байта на страницу. Чтобы определить, какая микросхема подключена к процессору Blackfin, код Boot ROM читает регистр состояния DataFlash, который содержит биты плотности устройства (device density bits). Если они равны 1011 (в двоичном коде), то Boot ROM предполагает, что это AT45DB161B, и адресует её соответственно. Иначе код предполагает, что подключена AT45DB041B или AT45DB081B и адресует их соответствующим образом. После выхода кода Boot ROM silicon revision 0.3 компания Atmel представлена более новые модели своих микросхем DataFlash (более того, перечисленные микросхемы AT45DB041B, AT45DB081B, AT45DB161B уже устаревшие, и не рекомендуются для использования в новых устройствах). Если пользователь планирует использовать одну из более новых микросхем DataFlash, то следует тщательно изучить даташит и убедиться, что устройство имеет 264 байт на страницу, иначе последовательность загрузки завершится неудачей.

Для подпрограммы детектирования SPI, описанной выше, код Boot ROM для silicon revision 0.2 и ниже будет просто проверять приходящие данные через вывод MISO на равенство 0x00 (первый байт файла загрузки). Код Boot ROM для silicon revision 0.3 проверяет приходящие данные через MISO на неравенство 0xFF. По этой причине файлы загрузки SPI, собранные для 0.2 и ниже должны содержать в первом байте 0x00. Для silicon revision 0.3, первый байт файла загрузки установлен в 0x40.

Регистр скорости SPI (SPI Baud Rate register, SPI0_BAUD [9]) установлен в значение 133, что при частоте системной шины 54 МГц даст скорость обмена по шине SPI, равную 54000 / (2*133) = 203 кГц, т. е. 203000 бит/сек. К примеру, на плате ADSP-BF533 EZ-KIT Lite системная частота по умолчанию 54 МГц.

На диаграммах ниже показана последовательность загрузки для режима SPI Master boot с использованием 16-битно адресуемой памяти SPI (25LC640 компании Microchip). Файл загрузки используется тот же самый, который показан в листинге 3. Все диаграммы захвачены на кристалле silicon revision 0.3.

Рис. 21 показывает полную последовательность загрузки SPI Master mode boot.

EE 240 Diagram SPI Master Mode Boot fig21

Рис. 21. Диаграмма времени для SPI Master Mode Boot Sequence.

Сначала встроенный код Boot ROM определяет тип подключенной памяти SPI (адресуемая по 8/16/24 бита, или это Atmel DataFlash).

EE 240 SPI Master Mode Boot Sequence SPI Memory Detection Sequence fig22

Рис. 22. SPI Master Mode Boot Sequence: детектирование типа памяти SPI.

Обратите внимание, что рис. 22 получен захватом диаграмм на кристалле silicon revision 0.3. На silicon revision 0.2 сигнал тактов SPICLK будет установлен в лог. 1 до начала передач и между ними.

Код Boot ROM определил, что это память SPI, адресуемая 16 разрядами. Далее он выдает команду чтения и посылает адрес 0x0000 для чтения первого 10-байтного заголовка блока Init Code DXE.

EE 240 SPI Master Mode Boot Sequence 10 Byte Header Init Code DXE Count Block fig23

Рис. 23. SPI Master Mode Boot Sequence: загрузка 10 байт заголовка Init Code DXE Count Block.

Поскольку Init Code DXE Count Block является 4-байтным блоком ignore, то код Boot ROM затем выдаст команду чтения и пошлет за ней адрес 0x000E для 10 байт заголовка блока Block 1 Init Code DXE. После того, как заголовок прочитан, код Boot ROM будет знать, где блок Block 1 разместится в памяти, и сколько байт нужно поместить в это место.

EE 240 SPI Master Mode Boot Sequence 10 Byte Header Block1 Init Code DXE fig24

Рис. 24. SPI Master Mode Boot Sequence: загрузка 10 байт заголовка для Block 1 Init Code DXE.

После того, как эта информация обработана, код Boot ROM снова выдаст команду чтения и пошлет адрес 0x0018, чтобы загрузить содержимое Block 1 Init Code DXE.

EE 240 SPI Master Mode Boot Sequence Block1 Init Code DXE fig25

Рис. 25. SPI Master Mode Boot Sequence: загрузка данных Block 1 Init Code DXE.

Следующие опции загрузки относятся ко всем производным кристаллам от моделей ADSP-BF531/BF532/BF533.

[Silicon Revision 0.1]

Таблица 2. Режимы загрузки Silicon Revision 0.1.

BMODE[1:0] Описание
00 Выполнение из внешней 16-битной памяти, подключенной к ASYNC Bank0 (пропуск запуска кода Boot ROM).
01 Загрузка из 8/16 битной параллельной микросхемы FLASH/PROM. Поддерживается загрузка только из 8-битной памяти(1).
10 Загрузка через SPI из микросхемы памяти с 8-битной адресацией в режиме SPI Master mode.
11 Загрузка через SPI из микросхемы памяти с 16-битной адресацией в режиме SPI Master mode.

Примечание (1): поддерживается только режим загрузки из 8-разрядных параллельных микросхем памяти (8-bit boot). Если применена 16-разрядная микросхема flash, то данные в ней должны чередоваться с нулевыми байтами, чтобы симулировать 8-битную загрузку.

На Silicon revision 0.1 не поддерживаются блоки IGNORE и INIT.

Имейте в виду, что для Silicon Revision 0.1 должны быть зарезервированы адреса памяти 0xFF900000 .. 0xFF90000F (первые 16 байт L1 Data Bank B). Этот диапазон памяти используется кодом Boot ROM для хранения информации о каждом блоке внутри файла загрузки. После завершения загрузки эта память может использоваться приложением во время своего выполнения.

[Silicon Revision 0.2]

В кристаллах Silicon revision 0.2 был представлен режим загрузки 24-bit SPI. Стало возможным автоматически определять тип подключенной микросхемы памяти SPI (8/16/24 адресация). Также в silicon revision 0.2 появился функционал блока INIT.

Таблица 3. Режимы загрузки Silicon Revision 0.2.

BMODE[1:0] Описание
00 Выполнение из внешней 16-битной памяти, подключенной к ASYNC Bank0 (пропуск запуска кода Boot ROM).
01 Загрузка из 8/16 битной параллельной микросхемы FLASH/PROM. Поддерживается загрузка только из 8-битной памяти(1).
10 Зарезервировано.
11 Загрузка через SPI из микросхемы памяти с 8/16/24-битной адресацией в режиме SPI Master mode (на сигнале MISO нужен pull-up резистор)(2)(3).

Примечания:

(1) Поддерживается только режим загрузки из 8-разрядных параллельных микросхем памяти (8-bit boot). Если применена 16-разрядная микросхема flash, то данные в ней должны чередоваться с нулевыми байтами, чтобы симулировать 8-битную загрузку.
(2) Блоки с заполнение нулями (Zero-fill blocks) для режима SPI Master в ревизии silicon revision 0.2 не поддерживается из-за бага в коде встроенного Boot ROM. Таким образом, нули должны напрямую присутствовать в данных загружаемого блока.
(3) Первый байт файла загрузки для SPI должен быть равен 0x00.

Обратите внимание, что для Silicon Revision 0.2 должны быть зарезервированы адреса памяти 0xFF807FE0 .. 0xFF807FFF (последние 32 байта L1 Data Bank A). Этот диапазон памяти используется кодом Boot ROM для хранения информации о каждом блоке внутри файла загрузки. После завершения загрузки эта память может использоваться приложением во время своего выполнения.

Примечания (1), (2), (3), приведенные выше, относятся к утилите elfloader только в том случае, если используется режим ревизии кристалла 0.2 (используйте ключ командной строки –si-revision 0.2), который является режимом по умолчанию для инструментария VisualDSP++ версии 3.5. Однако это будет изменено в будущих версиях среды, когда появится silicon revision 0.3.

[Silicon Revision 0.3]

В кристаллах Silicon revision 0.3 появился режим загрузки SPI slave booting. Режим SPI Master поддерживает устройства памяти DataFlash компании Atmel в дополнение к стандартным микросхемам памяти SPI с адресацией 8/16/24 бита. Также появился правильный режим 16-bit flash/PROM, и была исправлена поддержка программного сброса.

Таблица 4. Режимы загрузки Silicon Revision 0.3.

BMODE[1:0] Описание (также см. раздел "Описание специфики режимов загрузки Blackfin ")
00 Выполнение из внешней 16-битной памяти, подключенной к ASYNC Bank0 (пропуск запуска кода Boot ROM).
01 Загрузка из 8/16 битной параллельной микросхемы FLASH/PROM.
10 Загрузка через SPI в режиме SPI Slave mode (данные поступают от хоста SPI).
11 Загрузка из памяти SPI, адресуемой 8/16/24 битами, с поддержкой микросхем памяти Atmel AT45DB041B, AT45DB081B и AT45DB161B DataFlash® (хостом SPI выступает загружаемый процессор Blackfin).

Обратите внимание, для Silicon Revision 0.3 должны быть зарезервированы адреса памяти 0xFF807FF0 .. 0xFF807FFF (последние 16 байт L1 Data Bank A). Этот диапазон памяти используется кодом Boot ROM для хранения информации о каждом блоке внутри файла загрузки. После завершения загрузки эта память может использоваться приложением во время своего выполнения.

Чтобы разрешить использование возможностей silicon revision 0.3, утилита elfloader должна вызываться в режиме 0.3 (используйте ключ командной строки –si-revision 0.3).

Встроенный код Boot ROM для silicon revision 0.3 полностью обратно совместим с silicon revision 0.2. Пользователи кристаллов silicon revisions 0.2 и 0.3 должны запускать утилиту elfloader с ключом командной строки –si-revision 0.2.

Для просмотра содержимого готового файла загрузки, который делает утилита elfloader, есть бесплатная программа Blackfin Loader File Viewer (LdrViewer) [8]. При отображении она разбивает содержимое файла загрузки на категории отдельных входных файлов .DXE и отображает в этих категориях заголовки загружаемых блоков (показывая поля ADDRESS, COUNT и FLAG). Эта утилита поможет Вам проанализировать содержимое файла загрузки. Когда файл загрузки из листинга 3 открыт в LdrViewer, то его содержимое будет выглядеть следующим образом:

EE 240 Blackfin Loader File Viewer Utility fig26

Рис. 26. Утилита Blackfin Loader File Viewer.

Имейте виду, что утилита LdrViewer не входит в комплект инструментария VisualDSP++.

[Ссылки]

1. ADSP-BF533 Blackfin® Booting Process site:analog.com.
2. 151007EE240v4.zip - примеры кода, документация и утилиты, относящиеся к статье.
3. Blackfin: утилита elfloader.exe.
4. Blackfin ADSP-BF538.
5. ADSP-BF538: блок интерфейса внешней шины.
6. Running Programs from Flash on ADSP-BF533 Blackfin Processors site:analog.com.
7. Intel HEX: описание формата файла.
8. Утилита просмотра файла загрузки Blackfin.
9. ADSP-BF538: интерфейс SPI.
10U-Boot JTAG Boot UART LdrViewer site:blackfin.uclinux.org.