Проектирование с использованием процессоров Analog Devices. Создание автономного приложения
Процедура начальной загрузки процессора
В автономно работающих системах после подачи питания внутренняя память и оперативная внешняя память процессора (если она имеется) пусты, поэтому практически во всех случаях первое, что необходимо выполнить, — это загрузка кода и данных приложения из внешней энергонезависимой памяти или хост-процессора. Единственное исключение составляет ситуация, когда программа исполняется непосредственно из внешней энергонезависимой памяти (как правило, флэш-памяти), однако на практике этот вариант используется редко, и мы рассматривать его здесь не будем.
Процесс загрузки кода и данных приложения во внутреннюю и/или внешнюю память процессора называется начальной загрузкой (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). При включении питания платы или аппаратном сбросе процессора контроллер динамической памяти не инициализирован, и поэтому попытка размещения в динамической памяти любой информации приведет к некорректной работе приложения, если не предпринимать определенных мер. Кроме того, инициализационный код можно использовать для таких задач, как внесение изменений в настройки схемы формирования тактового сигнала (коэффициенты деления схемы ФАПЧ), изменение параметров различных аппаратных интерфейсов в целях ускорения процесса начальной загрузки, реализация альтернативных вариантов загрузки (загрузчик второго уровня), распаковка сжатой информации при загрузке для сокращения объема памяти, необходимой для хранения загружаемого кода и/или данных, выбора одного из нескольких возможных вариантов приложений для загрузки и т. п. Дополнительную информацию о различных вариантах применения инициализационного кода можно найти в документах [1–3].
Когда ПЗУ начальной загрузки обнаруживает блок, в заголовке которого установлен бит 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.
Параметры, управляющие делителями частот, мультиплексорами и выходными буферами, определяются полями регистров 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. Здесь же указывается путь к сформированному ранее исполняемому файлу, соответствующему инициализационному коду.
Повторный запуск сборки проекта с новыми настройками приведет к появлению в папке 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.
На этом процесс создания автономно работающего приложения в среде VisualDSP++ заканчивается. Завершив сеанс работы в VisualDSP++ и произведя перезапуск питания платы EZ-KIT Lite, вы должны увидеть тот же результат, что и при отладке приложения через эмулятор или Debug Agent.
Заключение
В этой статье был рассмотрен процесс создания автономно работающего приложения для платы ADSP-BF527 EZ-KIT Lite, которое загружается в процессор из внешней параллельной флэш-памяти, однако те же основные принципы распространяются и на многие другие модели процессоров и варианты начальной загрузки. Хорошее понимание процедуры начальной загрузки и структуры инициализационного кода позволит избежать многих проблем при переходе от отладки приложения в среде VisualDSP++ при помощи эмулятора или интерфейса Debug Agent к окончательной версии проекта, предназначенной для работы в автономном режиме.
Литература
- http://www.analog.com/static/imported-files/application_notes/EE-240_Rev4.pdf
- http://www.analog.com/static/imported-files/application_notes/EE257 v01.pdf
- http://www.analog.com/static/imported-files/application_notes/EE_308.Rev1.12.06.pdf
- http://www.analog.com/en/processors-dsp/blackfin/processors/ic-anomalies/resources/index.html
- http://www.micron.com/get-document/? documentId=32
- Сотников А. Проектирование с использованием процессоров Analog Devices. Первый проект для EZ-KIT Lite // Компоненты и технологии. 2010. № 9.