VisualDSP API программирования FLASH для процессоров Blackfin
Добавил(а) microsin
Тестирование встраиваемого приложения обычно подразумевает применение эмулятора JTAG для отладки исполняемого кода, который загружается в память целевого процессора. Ближе к окончанию разработки становится критически важным тестирование кода приложения, который загружается в процессор из flash, PROM или другого периферийного устройства. Часто эта фаза разработки сложна для полной автоматизации. Система VisualDSP++® представляет дополнительный набор API-функций (далее в тексте это будет называться Flash Programmer API), которые упрощают запись исполняемого кода (uploading, или прошивку) и образа данных в память flash. Используя эти новые функции API, образы приложения могут быть запрограммированы во flash, т. е. содержимое flash может быть заполнено или очищено.
Примечание: здесь приведен перевод апноута EE_311_Rev_1_12_2006.pdf с сайта Analog Devices [1].
Требования к аппаратуре и программному обеспечению. Интерфейс API плагина программирования (Flash Programmer plug-in) требует установленной системы разработки VisualDSP++ версии 4.5 или более новой (последняя версия VisualDSP++ 5.1.2.0, IDDE Version 8.0.7.22, сборка 30 мая 2013 года). Дополнительно нужна подходящая целевая система (плата), оборудованная всем необходимым для тестирования загрузки образов приложения в устройства памяти flash. К примеру, это может быть плата разработчика ADSP-BF533 EZ-KIT Lite® или ADSP-BF537 EZ-KIT Lite, которые позволяют разработать и проверить в работе код приложения и весь процесс, который описан в этой документации. Однако Flash Programmer API поддерживает все процессоры Blackfin®, т. е. его можно использовать с Вашими разрабатываемыми устройствами на основе процессоров Blackfin.
Функции API. Плагин Flash Programmer API предоставляет относительно малое подмножество функций:
EraseAll – стирает все содержимое устройства flash.
EraseBlock – стирает указанный (по номеру) сектор устройства flash.
FillFlash – заполняет память flash указанным количеством заданных данных.
LoadDriver – загружает в процессор программу драйвера прошивальщика *.dxe (flash device driver program), которая упрощает загрузку образа flash в микросхему памяти flash.
LoadFile – выгружает (upload, т. е. записывает) загружаемый образ кода приложения в устройство flash.
Flash Programmer API является частью общего VisualDSP++ API, которое позволяет пользователям создавать скрипты или программы на любом языке, которые поддерживают Automation [3].
Компания Analog Devices предоставляет скрипт примера (programFlash.vbs, см. врезку), чтобы продемонстрировать работу Flash Programmer API. Все примеры кода и команды ниже относятся к этому скрипту примера.
Этот скрипт относится к апноуту EE-311 Rev 1 (14 декабря 2006 года) [1], и его можно найти на страничке http://www.analog.com/ee-notes. Весь код примера был написан и тестировался вместе с VisualDSP++ 4.5 и ADSP-BF533 revision 0.2 (EZ-KIT Lite revision 1.3).
'-----------------------------------------------------' Константы:'-----------------------------------------------------Const formatIntelHex =0Const formatBinary =1Const formatASCII =2Const eraseAffected =0Const eraseAll =1Const eraseNone =2'-----------------------------------------------------' Переменные форматирования текста:'-----------------------------------------------------Dim NL
Dim TB
Dim TB2
Dim TB3
NL = vbNewLine
TB = vbTab
TB2 = TB+TB
TB3 = TB+TB+TB
usage ="cscript.exe --driver <driver file> [OPTIONS]"+NL+_
"REQUIRED:"+NL+_
NL+_
"--driver <driver file>"+TB+_
": specifies <driver file> for communication with the flash device"+NL+_
NL+_
"OPTIONS: "+NL+_
"--image <image file>"+TB+_
": specifies <image file> for loading into flash"+NL+_
"--offsetL [addr]"+TB+_
": address offset to use when executing image file load (default is 0x0)"+NL+_
"--format"+TB2+_
": format of the image file; 0 - Intel Hex (default), 1 - binary, 2 - ASCII"+NL+_
"--verifyWrites"+TB2+_
": verify write operations during the image file load (default is false)"+NL+_
"--eraseOption"+TB2+_
": option to clear the flash area where the image load is occurring;"+NL+_
TB3+_
" 0 - erase affected (default), 1 - erase all, 2 - erase none"+NL+_
"--fill"+TB3+_
": fill flash with values"+NL+_
"--boot"+TB3+_
": boot up the hardware board with the image in flash"+NL+_
"--offsetF [addr]"+TB+_
": address offset to use when executing fill (default is 0x0)"+NL+_
"--count [n]"+TB2+_
": number of values to write during fill operation (default is 16)"+NL+_
"--stride [s]"+TB2+_
": offset of the next write during fill operation (default is 1)"+NL+_
"--value [val]"+TB2+_
": value to be written into flash during fill (default is 0x0)"+NL+_
"--eraseAll"+TB2+_
": erase entire flash"+NL+_
"--eraseBlocks [0,1,..]"+TB+_
": erase specified sectors of flash (comma-separated list with no spaces);"+NL+_
TB3+_
" if sector list is ommitted, the default is 0,1,2,3"+NL
'-----------------------------------------------------' Вспомогательные переменные:'-----------------------------------------------------Dim index
'-----------------------------------------------------' Опции:'-----------------------------------------------------Dim doLoadImage
Dim doVerifyWrites
Dim doEraseAll
Dim doEraseBlocks
Dim doLoadDriver
Dim doFill
Dim doBoot
'-----------------------------------------------------' Значения:'-----------------------------------------------------Dim fpDriver
Dim LdrImage
Dim blocks
Dim eraseOption
Dim imageFormat
Dim imageOffset
Dim fillOffset
Dim fillCount
Dim fillStride
Dim fillValue
'-----------------------------------------------------' Начальные значения для переменных и опций скрипта:'-----------------------------------------------------
doLoadImage =False
doVerifyWrites =False
doEraseAll =False
doEraseBlocks =False
doLoadDriver =False
doVerifyWrites =False
doBoot =False
blocks = Array ( 0, 1, 2, 3 )
eraseOption = eraseAffected
imageFormat = formatIntelHex
imageOffset =0
fillOffset =0
fillCount =16
fillStride =1
fillValue =0
index =0'-----------------------------------------------------' Проверка использования скрипта:'-----------------------------------------------------If ( WScript.arguments.Count =0 ) Then
displayUsage
WScript.Quit ( 0 )
EndIf'-----------------------------------------------------------' Обработка выбранных пользователем опций командной строки:'-----------------------------------------------------------ForEach arg in WScript.arguments
If ( StrComp ( arg, "--driver" ) =0 ) Then
doLoadDriver =TrueIf ( ( index +1 ) <= WScript.arguments.Count ) Then
fpDriver = WScript.arguments ( index +1 )
EndIfElseIf ( StrComp ( arg, "--image" ) =0 ) Then
doLoadImage =TrueIf ( ( index +1 ) <= WScript.arguments.Count ) Then
LdrImage = WScript.arguments ( index +1 )
EndIfElseIf ( StrComp ( arg, "--fill" ) =0 ) Then
doFill =TrueElseIf ( StrComp ( arg, "--boot" ) =0 ) Then
doBoot =TrueElseIf ( StrComp ( arg, "--verifyWrites" ) =0 ) Then
doVerifyWrites =TrueElseIf ( StrComp ( arg, "--eraseAll" ) =0 ) Then
doEraseAll =TrueElseIf ( StrComp ( arg, "--eraseBlocks" ) =0 ) Then
doEraseBlocks =TrueIf ( ( index +1 ) <= WScript.arguments.Count ) Then
blocks = Split ( WScript.arguments ( index +1 ), "," )
EndIfElseIf ( StrComp ( arg, "--eraseOption" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
eraseOption = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--format" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
imageFormat = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--offsetL" ) =0 ) Then
doImageOffset =TrueIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
imageOffset = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--offsetF" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
fillOffset = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--count" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
fillCount = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--stride" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
fillStride = Eval ( temp )
EndIfElseIf ( StrComp ( arg, "--value" ) =0 ) ThenIf ( ( index +1 ) <= WScript.arguments.Count ) Then
temp = WScript.arguments ( index +1 )
temp = Replace ( temp, "0x", "&h" )
fillValue = Eval ( temp )
EndIfEndIf
index = index +1Next'-----------------------------------------------------' Печатает опции, выбранные пользователем (это сделано' для отладки самого скрипта):'-----------------------------------------------------SubcheckArgs ( )
WScript.StdOut.WriteLine "FPDriver: "+ FPDriver
WScript.StdOut.WriteLine "LdrImage: "+ LdrImage
WScript.StdOut.WriteLine "doEraseBlocks: "+CStr ( doEraseBlocks )
WScript.StdOut.WriteLine "doEraseAll: "+CStr ( doEraseAll )
WScript.StdOut.WriteLine "doLoadImage: "+CStr ( doLoadImage )
WScript.StdOut.WriteLine "doVerifyWrites: "+CStr ( doVerifyWrites )
WScript.StdOut.WriteLine "doBoot: "+CStr ( doBoot )
WScript.StdOut.WriteLine "eraseOption: "+CStr ( eraseOption )
WScript.StdOut.WriteLine "imageFormat: "+CStr ( imageFormat )
WScript.StdOut.WriteLine "imageOffset: "+CStr ( imageOffset )
WScript.StdOut.WriteLine "fillOffset: "+CStr ( fillOffset )
WScript.StdOut.WriteLine "fillCount: "+CStr ( fillCount )
WScript.StdOut.WriteLine "fillStride: "+CStr ( fillStride )
WScript.StdOut.WriteLine "fillValue: "+"0x"+ Hex ( fillValue )
WScript.StdOut.Write "eraseBlocks: "For i =0to UBound ( blocks )
WScript.StdOut.Write CStr ( blocks(i) ) +" "Next
WScript.StdOut.WriteLine ""EndSub'-----------------------------------------------------' Печатает подсказку по использованию скрипта:'-----------------------------------------------------SubdisplayUsage ( )
WScript.StdOut.Write usage
EndSub'-----------------------------------------------------' Подключение к объекту Idde через интерфейс COM' и инициализирует некоторые установки:'-----------------------------------------------------Set app = CreateObject( "VisualDSP.ADspApplication" )
app.Interactive =True
app.Visible =True'-----------------------------------------------------' Получает ссылку на объект плагина Flash Programmer:'-----------------------------------------------------
WScript.StdOut.WriteLine "Starting the FlashProgrammer plugin..."Set FPPlugin = app.PluginList.Item("Flash Programmer")
Set FlashProgrammer = FPPlugin.Open()
'-----------------------------------------------------' Загружает драйвер программатора (flash driver):'-----------------------------------------------------
WScript.StdOut.WriteLine "Loading the FP driver..."
FlashProgrammer.LoadDriver FPDriver
'-----------------------------------------------------' Сначала выполняет все опции по очистке, выбранные' пользователем:'-----------------------------------------------------If ( doEraseAll =True ) Then
WScript.StdOut.WriteLine "Erasing all flash..."
FlashProgrammer.EraseAll()
ElseIf ( doEraseBlocks =True ) Then
WScript.StdOut.WriteLine "Erasing Flash blocks..."For i =0To UBound ( blocks )
strBlock = blocks(i)
WScript.StdOut.WriteLine "Erasing block "+ strBlock +"..."
FlashProgrammer.EraseBlock CInt ( strBlock )
NextEndIf'-----------------------------------------------------' Выполняет все действия по заполнению flash,' выбранные пользователем:'-----------------------------------------------------If ( doFill =True ) ThenIf ( fillCount <0 ) Then
fillCount =16EndIf
WScript.StdOut.WriteLine "Filling flash: count "+CStr ( fillCount ) +"..."
FlashProgrammer.FillFlash fillOffset, fillCount, fillStride, fillValue
EndIf'-----------------------------------------------------' Загружает указанный пользователем файл образа:'-----------------------------------------------------If ( doLoadImage =True ) Then
WScript.StdOut.WriteLine "Programming Flash with the image File..."
FlashProgrammer.LoadFile LdrImage, imageFormat, doVerify, eraseOption, imageOffset
EndIf'-----------------------------------------------------' Переводит в режим загрузки (Boot up) целевую плату,' если пользователь выбрал эту опцию:'-----------------------------------------------------If ( doBoot =True ) Then
WScript.StdOut.WriteLine "Booting up the board from flash..."While ( app.ActiveSession.ActiveProcessor.BreakpointList.Count >0 ):
app.ActiveSession.ActiveProcessor.BreakpointList.RemoveBreakpointByIndex( 0 )
WEnd
app.MenuManager.ClickMenuItem "Settings:Boot Load...", False
WScript.Sleep ( 1000 )
EndIf
WScript.StdOut.WriteLine "All done!"
[Как обычно используется Flash Programmer API]
Чаще всего описанные API-функции применяются для выгрузки образа встраиваемого приложения (чаще всего это файл *.ldr в двоичном формате или файл *.hex) в память flash, находящейся на целевой плате (эта процедура может использоваться как для конечного производства либо как часть большого набора тестов). Чтобы выполнить эти действия, скрипты могут быть написаны на различных языках программирования, которые поддерживают технологию Automation [3].
Скрипт примера (programFlash.vbs) выполняет следующие действия:
• Подключение к объекту VisualDSP++ IDDE. • Получение ссылки (handle) на объект плагина Flash Programmer. • Загружает программу драйвера чипа flash (flash chip driver program) в целевой процессор. • Стирает все (или указанные) сектора памяти flash. • Заполняет область памяти flash значением, указанным пользователем. • Выгружает (записывает) выбранный файл образа приложения в память flash. • Опционально посылает сигнал мягкого сброса (soft reset) для загрузки и запуска процессором (boot up) записанного образа приложения.
Примечание: пример скрипта, использующего технологию Automation, требует, чтобы среда разработки VisualDSP++ IDDE была открыта, и была установлена соответствующая рабочая сессия аппаратного отладчика (hardware debug). Чтобы автоматизировать создание сессии в скрипте, обратитесь к VisualDSP++ online Help, где имеется полное описание всего интерфейса автоматизации VisualDSP++. Также можно обратиться к офлайн-справке VisualDSP++ (меню Help -> Contents... -> Automation), или см. [2].
Подключение к IDDE и получение Flash Programmer Handle. Реализация всех вышеописанных шагов довольно проста с применением VisualDSP++ API. Часть скрипта примера, относящаяся к работе с flash, начинается с получения ссылки (handle) на объект плагина Flash Programmer, как это показано в Листинге 1.
'Листинг 1. Здесь скрипт получает handle, указывающую
'на Flash Programmer Plug-In Object:
WScript.StdOut.WriteLine "Starting the FlashProgrammer plugin..."
Set FPPlugin = app.PluginList.Item("Flash Programmer")
Set FlashProgrammer = FPPlugin.Open()
Загрузка Flash Driver. Далее загружается драйвер flash в целевой процессор:
FlashProgrammer.LoadDriver FPDriver
Поскольку скрипт работает с платой ADSP-BF533 EZ-KIT Lite, то драйвер flash был предоставлен компанией Analog Devices. Однако плагин Flash Programmer может обмениваться с пользовательскими драйверами flash, которые могут работать с разными чипами памяти.
Стирание Flash. Скрипт проверяет опции, которые задают, нужно или нет стереть (erase) память, как это показано в Листинге 2.
'Листинг 2. Проверка опций очистки:
If ( doEraseAll =True ) Then
WScript.StdOut.WriteLine "Erasing all flash..."
FlashProgrammer.EraseAll()
Обратите внимание, что этот скрипт предоставляет 2 способа очистки flash: блок за блоком, и всю память flash целиком. Полная очистка flash осуществляется одной строкой команды, и поблочная очистка выполняется с помощью цикла for.
Заполнение Flash. Подобно предыдущим операциям, заполнение flash нужным значением выполняется одной строкой кода. Соответствующая часть скрипта проверяет опцию заполнения (fill option), которая могла бы быть выбрана пользователем, и выполняет нужные действия, как это показано в Листинге 3.
'Листинг 3. Часть скрипта, которая выполняет заполнение Flash:
Запись образа приложения. Листинг 4 демонстрирует запись (uploading) двоичного файла приложения в память flash.
'Листинг 4. Upload Application Image:
If ( doLoadImage =True ) Then
WScript.StdOut.WriteLine "Programming Flash with the image File..."
FlashProgrammer.LoadFile LdrImage, imageFormat, doVerify, eraseOption, imageOffset
EndIf
Запуск записанного приложения (booting). В этом месте основная работа скрипта завершена. На последнем шаге, который необязателен, посылается сигнал перезапуска процессора для загрузки приложения (как это показано в Листинге 5).
'Листинг 5. Отправка процессору Boot Signal:
If ( doBoot =True ) Then
WScript.StdOut.WriteLine "Booting up the board from flash..."While ( app.ActiveSession.ActiveProcessor.BreakpointList.Count >0 ):
app.ActiveSession.ActiveProcessor.BreakpointList.RemoveBreakpointByIndex(0)
WEnd
app.MenuManager.ClickMenuItem "Settings:Boot Load...", False
WScript.Sleep ( 1000 )
EndIf
Код в Листинге 5 содержит одну тонкость. Перед запуском загрузки скрипт удаляет точки останова (breakpoints), которые могли быть введены программой драйвера чипа flash. Это сделано для того, чтобы код целевого процессора работал без каких-либо остановок. Если целевой процессор должен быть остановлен (halted) на определенном символе кода или определенном адресе, нужные точки останова могут быть введены с использованием соответствующего VisualDSP++ API [2].
Примечание: отправка сигнала boot-up процессору доступна только если имеется соединение агента отладки (Debug Agent) с целевой платой. Соединения эмулятор ICE сами по себе не предоставляют такой функциональности. На рис. 1 показаны нужные соединения.
Рис. 1. Обмен данными между хостом отладки (компьютер, на котором работает API VisualDSP++) и программируемым чипом Flash через Flash Programmer API.
И наконец, последняя часть кода скрипта ждет 1 секунду, чтобы предоставить процессору время загрузить (bootstrap) самого себя и запустить нужный кусок кода приложения (процедура загрузки приложения Blackfin описана в статье [4]). Если это необходимо, может быть реализован более изощренный метод управления запуском приложения (например, применены точки останова), что делается с помощью соответствующего VisualDSP++ Automation API [2].
[Запуск скрипта]
В скрипте примера также содержится информация по использованию, которая будет отображена скриптом, если его запустить без указания опций в командной строке. Ниже приведены типичные примеры использования скрипта для прошивки файла образа приложения в память flash.
Обратите внимание, что скрипт требует указания абсолютных путей до файла драйвера и до файла образа программы пользователя. Также скрипт требует, чтобы среда разработки VisualDSP++ была открыта, и в ней была активирована корректная сессия отладки (hardware debug session).
Чтобы заполнить память flash указанными значениями, скрипт может быть запущен следующим образом:
Когда происходит заполнение памяти flash, или выгрузка в неё файла образа программы, Вы предварительно должны очистить соответствующие сектора flash. В обоих приведенных выше примерах стирается вся память целиком (или первые 2 сектора), прежде чем будет осуществлено либо заполнение памяти, либо выгрузка файла.
[Общие замечания]
Flash Programmer automation API ценно тем, что предоставляет управление памятью flash и инициализацией процессора для отладки. С помощью этого API память flash может быть предварительно заполнена известными значениями, чтобы можно было проверить результат загрузки процессора. Таким же методом память flash может быть использована как хранилище библиотечных подпрограмм и больших таблиц данных (которые были предварительно были скомпилированы как файлы образа flash), которые можно загрузить или стереть во время тестирования основной программы приложения.
Flash Programmer API работает при соединениями с ICE (In-Circuit Emulator, или JTAG-отладчик) или агентом отладки (Debug Agent, плата разработчика EZ-KIT Lite). Гибкость и простота API позволяют достичь нужной цели за более короткое время. Например, инженер службы тестирования может использовать простой сценарий для перепрошивки неправильно функционирующего устройства.
Еще одно достоинство Flash Programmer API в том, что оно может работать с пользовательским оборудованием и специализированными микросхемами памяти. Поскольку flash driver это ни что иное, как обычная программа, скомпилированная для целевого процессора, то пользовательские драйверы могут быть созданы для любых микросхем памяти flash с использованием инструментария VisualDSP++.
Обратитесь к разделам онлайн-справки VisualDSP++ в меню Tools -> Flash Programmer для получения дополнительной информации по написанию пользовательских драйверов flash, удовлетворяющих рабочему окружению Flash Programmer API. Также см. примеры кода драйверов (Flash Programmer driver) в примерах кода каталога установки VisualDSP++ (например, в каталоге Blackfin \ Examples \ ADSP-BF538F EZ-KIT Lite \ Flash Programmer находятся примеры проектов драйвера программирования внутренней и внешней памяти для процессора Blackfin ADSP-BF538).
[Краткое описание опций скрипта]
Эту подсказку выведет скрипт programFlash.vbs, если запустить его без опций.
cscript.exe --driver < driver file > [ОПЦИИ]
ОБЯЗАТЕЛЬНО СЛЕДУЕТ УКАЗАТЬ:
--driver < driver file >: указывает файл драйвера, который осуществляет
весь обмен с микросхемой памяти flash
ОПЦИИ:
--image < image file > : указывает файл образа, который будет загружен во flash
--offsetL [addr] : задает смещение адреса, по которому должен быть записан
файл образа, по умолчанию смещение равно 0x0
--format : задает формат файла образа
0 означает Intel Hex (*.hex, установка по умолчанию)
1 это двоичный формат (*.ldr)
2 формат ASCII
--verifyWrites : задает проверять записываемые данные файла образа
(по умолчанию false, т. е. не проверять)
--eraseOption : опция очистки области flash при записи файла образа
0 означает стирать только занимаемые программой сектора
(это настройка по умолчанию), 1 полное стирание всей,
микросхемы flash, 2 стирание не используется
--fill : заполнение памяти flash указанными значениями
--boot : вызовет загрузку системы после записи файла образа
--offsetF [addr] : смещение адресa для функции заполнения (fill),
по умолчанию смещение 0x0
--count [n] : количество значений для записи операции fill,
по умолчанию 16
--stride [s] : смещение для следующих друг за другом записей
операции fill (по умолчанию смещение 1)
--value [val] : значение, которое будет записано операцией fill,
по умолчанию 0x0
--eraseAll : стереть всю память flash
--eraseBlocks [0,1,..] : стереть указанные секторы flash. Указывается список
значений, следующих друг за другом через запятую,
без пробела. Если список опущен то используется
список по умолчанию 0,1,2,3