Проектирование с использованием процессоров Analog Devices. Создание автономного приложения

№ 6’2011
PDF версия
Переход от написания и отладки кода с использованием демонстрационной платформы EZ-KIT Lite или эмулятора к созданию автономно работающего приложения зачастую вызывает трудности у начинающих разработчиков и требует от них хорошего понимания процедуры начальной загрузки процессора. В этой статье, которая завершает цикл, посвященный проектированию программного обеспечения для процессоров компании Analog Devices, рассмотрен простой проект автономного приложения для платы ADSP-BF527 EZ-KIT Lite, осуществляющий запись фрагмента речевого сигнала в динамическую память и его последующее воспроизведение. На его примере мы обсудим ряд аспектов, связанных с начальной загрузкой, написанием инициализационного кода и внутрисхемным программированием памяти на плате с процессором.

Процедура начальной загрузки процессора

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

Процесс загрузки кода и данных приложения во внутреннюю и/или внешнюю память процессора называется начальной загрузкой (booting). Управление начальной загрузкой осуществляется при помощи небольшой программы, располагающейся в интегрированном на кристалле модуле ПЗУ начальной загрузки (Boot ROM). Сама программа, отвечающая за начальную загрузку процессора, называется загрузчиком первого уровня.

Загрузчик первого уровня анализирует состояние внешних выводов BMODE процессора в момент снятия сигнала аппаратного сброса и выполняет процедуру чтения потока данных специального формата из внешнего устройства. Тип внешнего устройства и соответствующая подпрограмма чтения выбираются в соответствии с прочитанным кодом BMODE. Возможные варианты источников загрузки с указанием кодов BMODE для процессора ADSP-BF527(C) перечислены в таблице.

Таблица. Режимы начальной загрузки процессора ADSP-BF527 (C)

BMODE[3:0] Описание
0000 Процессор не загружается, выполняется команда IDLE
0001 Загрузка из внешней 8- или 16-битной флэш-памяти
0010 Загрузка из 16-битного асинхронного FIFO
0011 Загрузка из последовательной памяти с интерфейсом SPI
0100 Загрузка из хоста через интерфейс SPI
0101 Загрузка из последовательной памяти с интефейсом TWI
0110 Загрузка из хоста через интерфейс TWI
0111 Загрузка из хоста через интерфейс UART0
1000 Загрузка из хоста через интерфейс UART1
1001 Зарезервированная комбинация
1010 Загрузка из памяти SDRAM
1011 Загрузка из интегрированной памяти OTP
1100 Загрузка из 8-битной NAND флэш-памяти через порт F
1101 Загрузка из 8-битной NAND флэш-памяти через порт H
1110 Загрузка из хоста в режиме 16-битного DMA
1111 Загрузка из хоста в режиме 8-битного DMA

Поток данных, размещаемый во внешнем устройстве, формируется утилитой под названием «загрузчик» (elfloader.exe). Эта утилита выполняет разбор входного исполняемого файла (.DXE), который используется при отладке и исполнении приложения с помощью симулятора, эмулятора или интерфейса Debug Agent платы EZ-KIT Lite, и генерирует выходной файл с расширением .LDR, он же состоит из набора блоков кода и данных, сопровождаемых 10-байтными заголовками. Каждый заголовок включает в себя следующие поля:

  • ADDRESS (4 байт) — адрес в карте памяти процессора, по которому должен быть размещен блок.
  • COUNT (2 байт) — количество байтов в блоке.
  • FLAG (2 байт) — команды управления, наиболее важными из которых являются флаги:
    • ZEROFILL — указывает на то, что блок соответствует буферу данных, состоящему из одних нулей, а программа, содержащаяся в ПЗУ начальной загрузки, должна записать COUNT нулевых байтов, начиная с адреса ADDRESS в памяти.
    • INIT — указывает на то, что этот блок содержит инициализационный код, который должен быть выполнен сразу после загрузки.
    • FINAL — указывает на то, что это последний блок в последовательности, после загрузки которого должен быть выполнен переход по адресу вектора прерывания, хранящемуся в регистре EVT1.

Алгоритм процедуры начальной загрузки процессора поясняет рис. 1.

Алгоритм процедуры начальной нагрузки

Инициализационный код

Инициализационный код — это подпрограмма, которая позволяет производить различные действия еще до момента загрузки основного приложения во внутреннюю и/или внешнюю память процессора. Он может быть использован для реализации различных функций, наиболее типичной среди которых является инициализация контроллера динамической памяти SDRAM (или DDR в процессорах ADSP-BF54x). При включении питания платы или аппаратном сбросе процессора контроллер динамической памяти не инициализирован, и поэтому попытка размещения в динамической памяти любой информации приведет к некорректной работе приложения, если не предпринимать определенных мер. Кроме того, инициализационный код можно использовать для таких задач, как внесение изменений в настройки схемы формирования тактового сигнала (коэффициенты деления схемы ФАПЧ), изменение параметров различных аппаратных интерфейсов в целях ускорения процесса начальной загрузки, реализация альтернативных вариантов загрузки (загрузчик второго уровня), распаковка сжатой информации при загрузке для сокращения объема памяти, необходимой для хранения загружаемого кода и/или данных, выбора одного из нескольких возможных вариантов приложений для загрузки и т. п. Дополнительную информацию о различных вариантах применения инициализационного кода можно найти в документах [13].

Когда ПЗУ начальной загрузки обнаруживает блок, в заголовке которого установлен бит INIT, загрузчик первого уровня загружает его в память процесса и выполняет вызов функции, содержащейся по начальному адресу блока. В связи с этим инициализационный код должен закачиваться командой RTS (возврат из подпрограммы), что гарантирует корректный возврат в программу загрузчика первого уровня.

Инициализационный код создается как отдельный проект VisualDSP++, выходом которого является исполняемый файл .DXE. Единственное отличие проекта с инициализационным кодом от обычного проекта заключается в том, что в первом случае проект содержит только одну вызываемую подпрограмму и, следовательно, больше похож на библиотеку. Исходный текст инициализационного кода для процессоров семейства ADSP-BF53x пишется на языке ассемблера, а для более новых семейств процессоров Blackfin он может создаваться как на языке ассемблера, так и на C/С++.

Далее мы рассмотрим максимально упрощенный пример инициализационного кода (листинг 1), обеспечивающего изменение тактовых частот процессора и настройку контролера SDRAM.

#include <cdefBF52x_base.h>
#include <ccblkfn.h>
#include <sysreg.h>
#include <bfrom.h>
void initcode(void)
{
unsigned short *pTmp;
ADI_SYSCTRL_VALUES init;
init.uwVrCtl = 0x70B0;
init.uwPllCtl = 0x2000;
init.uwPllLockCnt = 0x0200;
*pPLL_DIV = 0x0003;
bfrom_SysControl(SYSCTRL_VRCTL|SYSCTRL_INTVOLTAGE|SYSCTRL_PLLCTL|
SYSCTRL_LOCKCNT|SYSCTRL_WRITE,&init,NULL);
if(!(*pEBIU_SDSTAT & SDRS)) return;
while((*pEBIU_SDSTAT & SDCI) != SDCI) {}
*pEBIU_SDSTAT |= SDEASE;
*pEBIU_SDRRC = 0x0407;
*pEBIU_SDBCTL = 0x0025;
*pEBIU_SDGCTL = 0x0089998D;
ssync();
pTmp = (unsigned short*) 0x0;
*pTmp = 0xBEEF;
while((*pEBIU_SDSTAT & SDRS) == SDRS) {}
sysreg_write(reg_LC0,0);
sysreg_write(reg_LC1,0);
}

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

Код, приведенный в примере, создан на основе проекта инициализационного кода для платы ADSP-BF527 EZ-Kit Lite, который поставляется в составе пакета VisualDSP++ и находится, наряду с проектами инициализационного кода для других плат EZ-KIT Lite, в папке Blackfinldrinit_code установочного каталога VisualDSP++.

В новых процессорах семейств Blackfin, начиная с ADSP-BF52x и ADSP-BF54x, доступ к регистрам схемы ФАПЧ и регулятора напряжения должен осуществляться не непосредственно, а через функцию bfrom_SysControl(), которая реализована в интегрированном на кристалле ПЗУ. Эта функция принимает в качестве параметров три аргумента. Первый аргумент — это набор флагов, указывающих тип операции (чтение, запись или сброс), а также какие регистры будут записаны или прочитаны. Второй аргумент — это указатель на структуру типа ADI_SYSCTRL_VALUES, поля которой соответствуют отдельным регистрам схемы ФАПЧ и регулятора напряжения. Эта структура определена в заголовочном файле bfrom. h. И наконец, третий аргумент зарезервирован, и на его позиции в функцию должен передаваться пустой указатель (NULL). Использовать функцию bfrom_SysControl () следует очень осторожно, поскольку в некоторых версиях кристаллов она не работает или работает с ограничениями. В связи с этим необходимо предварительно внимательно изучить перечень аномалий на конкретный используемый процессор (errata sheet), который можно найти на сайте компании Analog Devices [4]. В рассматриваемом примере предполагается, что используется кристалл с ревизией 0.2.

Процессор на плате ADSP-BF527 EZ-KIT Lite тактируется сигналом CLKIN от кварцевого генератора с частотой 25 МГц. Внутренние тактовые частоты ядра (CCLK) и системы (SCLK) формируются при помощи схемы ФАПЧ и набора мультиплексоров и делителей частоты, как показано на рис. 2.

Схема формирования тактовых сигналов процессора Blackfin

Рис. 2. Схема формирования тактовых сигналов процессора Blackfin

Параметры, управляющие делителями частот, мультиплексорами и выходными буферами, определяются полями регистров PLL_CTL и PLL_DIV. По умолчанию после сброса устанавливаются следующие значения: DF = 0 (CLKIN подается на схему ФАПЧ напрямую без деления на 2), MSEL = 5 (частота ГУН = 5×fCLKIN), CSEL = 0 (частота CCLK равна частоте ГУН), SSEL = 4 (частота SCLK в 4 раза ниже частоты ГУН), BYPASS = 0, PWDN = 0. Таким образом, изначально процессор работает с тактовыми частотами, которые значительно ниже потенциально возможных (600 и 133 МГц для CCLK и SCLK соответственно). В рассматриваемом примере значения полей делителей изменяются на следующие: MSEL = 16, CSEL = 0 и SSEL = 4, что соответствует fCCLK = 400 МГц и fSCLK = 133 МГц.

Обратите внимание на то, что запись в регистр PLL_CTL осуществляется непосредственно, а не через функцию bfrom_SysControl (), из-за аномалии кристалла номер 05000440.

Для нормальной работы процессора на выбранных частотах недостаточно просто изменить настройки схемы формирования тактовых сигналов. Дело в том, что процессор способен работать при частоте SCLK более 100 МГц, только если напряжения питания периферии (VDDEXT) и памяти (VDDMEM) равны 2,5 В, а напряжение питания ядра (VDDINT), которое формируется при помощи внутреннего регулятора напряжения, не ниже 1,14 В. В то же время, по умолчанию, после сброса напряжение VDDINT устанавливается равным 1,1 В. Чтобы изменить уровень напряжения питания ядра, необходимо записать новое значение в поле VLEV регистра управления регулятором напряжения (VR_CTL). В рассматриваемом примере в это поле записывается комбинация битов 1011, что соответствует напряжению питания 1,2 В.

После настройки тактовых частот производится инициализация контроллера SDRAM. Значения, записываемые в поля регистров контроллера SDRAM, определяются на основании информации, которая дана в техническом описании на используемую микросхему (микросхемы) памяти, и выбранной конфигурации памяти. На плате ADSP-BF527 EZ-KIT Lite установлена одна микросхема памяти SDRAM фирмы Micron MT48LC32M16A2TG-75, имеющая объем 64 Мбайт и конфигурацию 32M×16 [5]. Разрядность адреса столбца SDRAM в используемой конфигурации составляет 10 бит. Эти параметры определяют значение, записываемое в регистр EBIU_SDBCTL.

Как обсуждалось выше, в примере выбрана максимально возможная частота fSCLK (133 МГц), поэтому в соответствии с таблицей спецификаций для микросхемы памяти с градацией –75 параметр CAS Latency (поле CL регистра EBIU_SDGCTL) равен 3.

Значения полей TRCD, TWR, TRP и TRAS регистра EBIU_SDGCTL определяются на основании минимальных значений соответствующих параметров спецификации и переводятся в периоды частоты fSCLK:

tRAS = 44 нс; TRAS = [44 нс/7,5 нс] = 6;

tRP = 20 нс; TRP = [20 нс/7,5 нс] = 3;

tRCD = 20 нс; TRCD = [20 нс/7,5 нс] = 3;

tWR = 1/fSCLK + 7,5 нс = 15 нс; TWR = [5 нс/7,5 нс] = 2.

Значение делителя, записываемого в регистр EBIU_SDRRC для задания частоты регенерации SDRAM, рассчитывается по формуле:

RDIV = ((fSCLK×tREF)/NRA)–(TRAS+TRP),

где tREF = 64 мс — значение периода регенерации, взятое из технического описания микросхемы памяти; NRA = 8192.

Таким образом,

RDIV = ((fSCLK×tREF)/NRA)–(TRAS+TRP) = ((133×106×64×10–3)/8192)–9 = [1030,0625] = 1031

(0х407 в шестнадцатеричной системе счисления).

Чтобы инициировать процедуру инициализации памяти SDRAM, после настройки регистров контроллера выполняется запись произвольного значения в ячейку с адресом 0.

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

Файл описания компоновщика (.LDF), используемый в процессе компоновки инициализационного кода, приведен в листинге 2.

#define CODE_BASE 0xFFA00000
#define DATA_BASE 0xFF804000
#define BANK_LENGTH 0x4000
$OBJECTS = $COMMAND_LINE_OBJECTS;
$LIBRARIES = $COMMAND_LINE_OBJECTS, libdsp532y.dlb;
MEMORY
{
MEM_INITCODE { TYPE(RAM) WIDTH(8) START(CODE_BASE) LENGTH(BANK_LENGTH) }
MEM_INITDATA { TYPE(RAM) WIDTH(8) START(DATA_BASE) LENGTH(BANK_LENGTH) }
}
PROCESSOR p0
{
RESOLVE( _initcode, CODE_BASE )
KEEP(_initcode)
OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
SECTIONS
{
L1_CODE
{
INPUT_SECTION_ALIGN(4)
INPUT_SECTIONS( $OBJECTS(L1_code) $LIBRARIES(L1_code) )
INPUT_SECTIONS( $OBJECTS(program) $LIBRARIES(program) )
} > MEM_INITCODE
L1_DATA
{
INPUT_SECTION_ALIGN(4)
INPUT_SECTIONS( $OBJECTS(L1_data) $LIBRARIES(L1_data) )
INPUT_SECTIONS( $OBJECTS(data1) $LIBRARIES(data1) )
} > MEM_INITDATA
}
}

Листинг 2. LDF-файл для проекта инициализационного кода

Создание основной части приложения

Основное приложение в рассматриваемом примере будет осуществлять запись в динамическую память и последующее воспроизведение фрагмента звукового сигнала. Настройка параметров ввода и вывода звукового сигнала через интегрированный аудиокодек подробно рассматривалась в [6], поэтому вопросы записи регистров кодека через порт SPI и конфигурирования порта SPORT мы повторно обсуждать не будем. Для снижения нагрузки на ядро процессора при взаимодействии с памятью SDRAM запись и чтение фрагмента сигнала будет выполняться в режиме DMA. Чтобы упростить проект, в нем будут использованы однократные пересылки DMA (режим Stop) с остановкой по завершении пересылки буфера данных. Поскольку максимальный размер блока, который можно пересылать в режиме одномерного DMA, составляет 64 кбайт, для работы с большими объемами данных при использовании однократных пересылок следует применить режим двумерного DMA. Процедура настройки каналов DMA для приема и передачи 32-битных слов через порт SPORT (каналы 3 и 4 соответственно) в режиме двумерного однократного DMA с генерацией прерывания по завершении пересылки всего блока данных имеет следующий вид:

*pDMAn_X_COUNT = SIZE_X;
*pDMAn¬_Y_COUNT = SIZE_Y;
*pDMAn_X_MODIFY = 4;
*pDMAn_Y_MODIFY = 4;
*pDMAn_START_ADDRESS = BUFFER_ADDR;
*pDMAn_CONFIG = 0x009B; (при приеме) или *pDMAn_CONFIG = 0x0099; (при передаче)

Здесь n — это номер канала; SIZE_X*SIZE_Y = полное количество элементов в буфере, BUFFER_ADDR — начальный адрес буфера с данными, который необходимо разместить в динамической памяти.

Запуск приемного канала DMA при записи и передающего канала DMA при воспроизведении будет осуществляться после нажатия пользовательских кнопок PB1 и PB2 соответственно. Эти кнопки активируют сигналы на линиях порта G ввода/вывода общего назначения PG0 и PG13. Чтобы настроить соответствующие выводы процессора на вход и разрешить формирование прерываний, необходимо запретить использование выводов для альтернативных функций в регистре PORTx_FER (x — буквенный код порта), установить в единицу биты 0 и 13 регистра PORTxIO_INEN, управляющего разрешением входных сигналов общего назначения, и выбрать тип прерывания (активность по одному фронту, обоим фронтам или уровню) при помощи регистров PORTxIO_EDGE, PORTxIO_BOTH и PORTxIO_POLAR. Каждый из портов общего назначения в процессоре Blackfin может генерировать два прерывания — A и B. За разрешение прерываний от модуля порта общего назначения отвечают регистры маскирования прерываний PORTxIO_MASKA и PORTxIO_MASKB, PORTxIO_MASKA_SET и PORTxIO_MASKB_SET или PORTxIO_MASKA_TOGGLE и PORTxIO_MASKB_TOGGLE.

Таким образом, код для настройки прерывания A порта G по нажатию кнопки PB1 и прерывания B порта G по нажатию кнопки PB2 будет иметь вид:

*pPORTG_FER &= 0x7FF7;
*pPORTGIO_INEN=0x2001;
*pPORTGIO_EDGE=0x2001;
*pPORTGIO_MASKA_SET = 0x1;
*pPORTGIO_MASKB_SET = 0x2000;

Предполагается, что фиксация прерывания будет осуществляться по переднему фронту соответствующего внешнего сигнала. Прерывания A и B порта G маскируются битами 8 и 9 регистра SIC_IMASK1 и по умолчанию отображаются в прерывание ядра IVG12.

Следовательно, для завершения настройки прерываний, инициируемых нажатием кнопок PB1 и PB2, в проект нужно добавить такие строки:

register_handler(ik_ivg12, Flags_ISR);
*pSIC_IMASK1 = 0x00000300;

Первое, что необходимо сделать в обработчике прерывания IVG12, — это проверить, какое из прерываний порта G на самом деле поступило, прочитав содержимое регистра PORTGIO. Если была нажата кнопка PB1, то в обработчике прерывания выполняется настройка канала 3 DMA (прием в режиме DMA через SPORT0), разрешается работа порта SPORT0 на прием, сбрасывается прерывание порта G очисткой бита 1 регистра PORTGIO и устанавливаются в false вспомогательные булевы переменные rec_enable и playback_enable, которые предотвращают неправильную последовательность нажатия кнопок. Обработка нажатия кнопки PB2 осуществляется схожим образом. Функции receive_dma_config и transmit_dma_config должны выполнять инициализацию канала DMA в соответствии с приведенным ранее описанием. Код обработчика прерываний A и B порта G приведен в листинге 3. Обратите внимание на то, что во избежание ошибочной работы разрешение приема и передачи через SPORT0 выполняется не на этапе настройки порта, а после настройки соответствующего канала DMA.

EX_INTERRUPT_HANDLER(Flags_ISR)
{
if(*pPORTGIO == 0x1)
{
if(rec_enable==true)
{
receive_dma_config(&data_buffer[0]);
*pSPORT0_RCR1 |= 1;
rec_enable=false;
playback_enable=false;
*pPORTGIO_CLEAR = 0x1;
}
}
else if(*pPORTGIO == 0x2000)
{
if(playback_enable==true)
{
transmit_dma_config(&data_buffer[0]);
*pSPORT0_TCR1 |= 1;
rec_enable=false;
playback_enable=false;
*pPORTGIO_CLEAR = 0x2000;
}
}
}

Листинг 3. Обработчик прерываний порта G

О завершении записи или воспроизведения блока данных сигнализирует прерывание канала DMA3 или канала DMA4 соответственно. Эти прерывания маскируются 16-м и 17-м битами регистра SIC_IMASK0 и по умолчанию отображаются в прерывании ядра IVG7. Таким образом, для завершения настройки прерываний приема и передачи SPORT0 в режиме DMA в исходный код необходимо добавить строки:

register_handler(ik_ivg9, Sport0_RX_ISR);
*pSIC_IMASK0 = 0x00030000;

В самом обработчике прерывания нужно проверить, какой из каналов его инициировал, прочитав регистр DMAx_IRQ_STATUS (x — номер канала DMA), запретить передачу или прием через SPORT, отключить канал DMA и сбросить прерывание записью единицы 1-го бита регистра DMAx_IRQ_STATUS. Также в обработчике прерываний устанавливаются в true переменные rec_enable и playback_enable, разрешая запись или воспроизведение. Код обработчика прерываний DMA SPORT0 приведен в листинге 4.

EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{
if(*pDMA3_IRQ_STATUS == 0x0001)
{
*pSPORT0_RCR1 &= 0xFFFE;
rec_enable=true;
playback_enable=true;
*pDMA3_CONFIG &= 0xFFFE;
*pDMA3_IRQ_STATUS = 0x0001;
}
else if(*pDMA4_IRQ_STATUS == 0x0001)
{
*pSPORT0_TCR1 &= 0xFFFE;
rec_enable=true;
playback_enable=true;
*pDMA4_CONFIG &= 0xFFFE;
*pDMA4_IRQ_STATUS = 0x0001;
}
}

Листинг 4. Обработчик прерываний DMA SPORT0

Для корректной работы приложения переменная rec_enable должна быть изначально установлена в true, а playback_enable — в false. Также для визуальной сигнализации о занятости/готовности процессора можно использовать в проекте светодиоды LED1, LED2 и LED3, которые подключены к выводам PF8, PG11 и PG12 процессора.

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

После того как проект полностью отлажен, нужно изменить тип формируемого выходного файла, чтобы вместо исполняемого файла .DXE в процессе сборки генерировался файл загружаемого образа .LDR. Для этого в диалоговом окне Project Options (меню Project → Project Options) среды VisualDSP++ на вкладке Project (рис. 3) из выпадающего списка Type следует выбрать пункт Loader File.

Диалоговое окно настроек проекта

Затем необходимо настроить параметры формирования образа. На плате ADSP-BF527 EZ-KIT Lite имеются микросхемы параллельной и последовательной флэш-памяти. В рассматриваемом примере мы выберем первый вариант. Чтобы указать на это утилите «загрузчик», в том же диалоговом окне Project Options на вкладке Load: Options (рис. 4) нужно выбрать тип Flash/PROM, формат файла Intel hex и разрядность памяти 16-bit. Здесь же указывается путь к сформированному ранее исполняемому файлу, соответствующему инициализационному коду.

Диалоговое окно настроек проекта (вкладка с настройками утилиты elfloader)

Повторный запуск сборки проекта с новыми настройками приведет к появлению в папке Debug проекта файла с расширением .LDR, который может быть записан во внешнюю параллельную флэш-память на плате EZ-KIT Lite.

Запись загружаемого образа во внешнюю память

При загрузке процессора из внешней памяти очень удобна возможность ее внутрисхемного программирования, которая избавляет от неудобств, связанных с применением дополнительных программаторов. В состав пакета VisualDSP++ входит утилита под названием FlashProgrammer, которая обеспечивает внутрисхемное программирование микросхем памяти, имеющихся на платах EZ-KIT Lite. Эта утилита работает с драйверами микросхем памяти, представляющими собой исполняемые файлы .DXE, которые загружаются в память процессора и позволяют производить стирание, чтение и запись флэш-памяти при работе под управлением эмулятора или интерфейса отладки Debug Agent. Драйверы, исходный код которых можно найти в каталоге с примерами для конкретной платы EZ-KIT Lite, написаны с помощью документированного набора API-функций и могут быть использованы для плат собственной разработки, если аппаратный интерфейс с флэш-памятью в них реализован идентично плате EZ-KIT Lite. Кроме того, пользователь может написать собственный драйвер на основе имеющихся примеров и описания API-функций.

Для запуска утилиты Flash Programmer необходимо выбрать в IDDE VisualDSP++ пункт меню Tools → Flash Programmer. В появившемся диалоговом окне (рис. 5) на вкладке Flash Driver необходимо указать путь к исполняемому файлу драйвера (в рассматриваемом примере — это BlackfinExamplesADSP-BF527 EZ-KITLite FlashProgrammerParallel BF527 EzFlashDriver_M29 W320 EB.dxe в установочном каталоге VisualDSP++) и нажать кнопку Load Driver. После отображения сообщения об успешной загрузке драйвера в память нужно перейти на вкладку Flash Programming, указать путь к сформированному ранее файлу .LDR и нажать кнопку Program.

Графический интерфейс утилиты Flash Programmer

На этом процесс создания автономно работающего приложения в среде VisualDSP++ заканчивается. Завершив сеанс работы в VisualDSP++ и произведя перезапуск питания платы EZ-KIT Lite, вы должны увидеть тот же результат, что и при отладке приложения через эмулятор или Debug Agent.

Заключение

В этой статье был рассмотрен процесс создания автономно работающего приложения для платы ADSP-BF527 EZ-KIT Lite, которое загружается в процессор из внешней параллельной флэш-памяти, однако те же основные принципы распространяются и на многие другие модели процессоров и варианты начальной загрузки. Хорошее понимание процедуры начальной загрузки и структуры инициализационного кода позволит избежать многих проблем при переходе от отладки приложения в среде VisualDSP++ при помощи эмулятора или интерфейса Debug Agent к окончательной версии проекта, предназначенной для работы в автономном режиме.

Литература

  1. http://www.analog.com/static/imported-files/application_notes/EE-240_Rev4.pdf
  2. http://www.analog.com/static/imported-files/application_notes/EE257 v01.pdf
  3. http://www.analog.com/static/imported-files/application_notes/EE_308.Rev1.12.06.pdf
  4. http://www.analog.com/en/processors-dsp/blackfin/processors/ic-anomalies/resources/index.html
  5. http://www.micron.com/get-document/? documentId=32
  6. Сотников А. Проектирование с использованием процессоров Analog Devices. Первый проект для EZ-KIT Lite // Компоненты и технологии. 2010. № 9.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *