реклама на сайте
подробности

 
 
> JUMP and RETURN на загружаемое приложение NIOS II
RLC
сообщение Oct 16 2017, 11:29
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-11-14
Из: СПб
Пользователь №: 83 740



Добрый день. Есть задача, подскажите инструмент и технологию с помощью которой её можно решить.
Описание существующей системы: Есть модуль с ПЛИС в которой реализован процессор NIOS II.
К NIOS II подключена ОЗУ, контроллер UART, реализованный в ПЛИС и другая переферия,
которая не относится к сути вопроса.
UART через приёмопередатчик подключен к порту COM ПК.
Через RS-232 и соответствующее ПО на ПК осуществляется чтение и запись данных в регистры адресного
пространства модуля, получение текстовой информации в консоль, запись программ в ОЗУ и их запуск на выполнение.
ОЗУ разделена в BSP на две части: HOST_PROGRAMM и LOAD_PROGRAMM.
HOST_PROGRAMM - это часть ОЗУ в которой хранится и выполняется программа запускаемая при подаче
питания на модуль и осуществляет связь с ПК по RS-232.
LOAD_PROGRAMM - это часть ОЗУ в которой хранится и выполняется программа записываемая по интерфейсу RS-232.
на данный момент программа загружаемая через RS-232 вызывается по адресу функции main(которая берётся из map-файла). Это сделано для
того что бы пропустить автоматическую инициализацию стека и после выполнения функции main вернуться без перезагрузки модуля
в HOST_PROGRAMM. Со стороны ПК, для пользователя, это выглядит как загрузка файла по определённому адресу в ОЗУ и ввода
адреса jump на загруженную программу, по которому осуществляется вызов лежащей там функции. В связи с тем что таких загружаемых
программ может быть несколько десятков и у каждой, естественно, свой адрес расположения функции main необходимо унифицировать
адрес расположения этой функции, т.е. привести к одному для любой загружаесмой программы LOAD_PROGRAMM, хотя бы с точки
зрения пользователя на ПК.
Вопрос: как унифицировать адрес расположения функции main в ПО? Что в этом мне может помочь? Можно это сделать линковщиком?
Спасибо за уделённое внимание.


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Raven
сообщение Dec 7 2017, 17:26
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 491
Регистрация: 16-01-05
Из: Санкт-Петербург
Пользователь №: 1 987



А почему с самого начала загружаемые программки/тесты/etc не рассматриваются как программы-приложения, рассчитанные на выполнение в среде, создаваемой HOST_PROGRAMM? Зачем вы LOAD_PROGRAMM компилируете со всеми ненужными им стартапными секциями и т.п. ?

Т.е., в идеале в составе HOST_PROGRAMM должен быть ELF-Loader, которому из UART подается ELF-файл конкретного теста/программки, он его размещает по памяти согласно его же содержимому, а потом передает управление в указанную точку. По завершении - получает управление обратно.
Go to the top of the page
 
+Quote Post
RLC
сообщение Dec 12 2017, 12:27
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-11-14
Из: СПб
Пользователь №: 83 740



Цитата(Raven @ Dec 7 2017, 20:26) *
А почему с самого начала загружаемые программки/тесты/etc не рассматриваются как программы-приложения, рассчитанные на выполнение в среде, создаваемой HOST_PROGRAMM? Зачем вы LOAD_PROGRAMM компилируете со всеми ненужными им стартапными секциями и т.п. ?

Я так понимаю что в среде это с использованием stack и heap HOST_PROGRAMM? Если я вас правильно понял, то отвечаю: у меня идея с самого начала была такая что бы выполнять из LOAD_PROGRAMM только функцию main. Для унификации её прилинковывать к какому-нибудь красивому адресу(0x10000, 0x 20000 и т.п.).Но в случае если NIOS будет использоваться в модуле где будет отдельный DDRx SDRAM на выделенной микросхеме, а раскручиваться HOST_PROGRAMM будет из ONCHIP RAM и LOAD_PROGRAMM будет работать с большим массивом данных, имеет смысл иметь независимое адресное пространство и отработанную технологию. Дело в том что я работаю не под конкретный заказ, а прорабатываю технологию для использования в будущем, поэтому принимаются во внимание самые изощрённые варианты возможных событий. В таком случае логика есть. А сам алгоритм загрузки используется в конторе на разных процессорах. В связи с этим все стартапные секции нужны, тк необходимо обеспечить ПОЛНУЮ независимость LOAD_PROGRAMM. Надеюсь я ответил на ваш вопрос =)
Цитата(Raven @ Dec 7 2017, 20:26) *
Т.е., в идеале в составе HOST_PROGRAMM должен быть ELF-Loader, которому из UART подается ELF-файл конкретного теста/программки, он его размещает по памяти согласно его же содержимому, а потом передает управление в указанную точку. По завершении - получает управление обратно.

Да, именно так. Маленькая поправка: у нас используется файл в формате *.bin. поэтому до загрузки скомпилированной программы в виде elf-файла превращаю этот файл в bin и потом его загружаю через нашу прогу загрузки файлов по uart. В bin файле находятся данные такие же как и в jic-файле образа epcs(при размещении ПО в epcs. Длинна секции данных , адресс копирования данных, двоичные данные, длинна данных, адресс копирования данных, двоичные данные и т.д. для каждой секции + заголовок отличающий этот bin-файл от просто двоичных данных которые тоже могут грузится по UART(и грузятся в наших изделиях)Подробнее в an458 о структуре epcs файла ПО) Путь преобразования такой: elf->flash->hex->pof->rpd->(через собственную программку обрезая лишнее и добавляя заголовок) bin файл.
С возвратом из этой LOAD_PROGRAMM дело обстоит сложнее тк у нас разный стек и полная инициализация процессора. Я сейчас доделываю такой вариант: После выдачи команды по UART совершаю из HOST_PROGRAMM программы на Си вызов функции по адресу старта LOAD_PROGRAMM, полученный при получении bin файла. В файле crt0.S LOAD_PROGRAMM перед инициализацией регистров, в самом начале, я в стек HOST_PROGRAMM(значение его вершины еще находится в регистре sp проца ) сохраняю все необходимые регистры(регистры общего назначения и служебные), в отдельный регистр сохраняю вершину стека HOST_PROGRAMM. После этого оставляю стандартный алгоритм инициализации процессора предложенный altera. После сохраняю в стек LOAD_PROGRAMM вершину стека HOST_PROGRAMM, вызываю alt_main, main. По завершению их работы восстанавливаю значение вершины стека HOST_PROGRAMM и возвращаю на место значение регистров процессора при HOST_PROGRAMM и выполняю ассемблерную команду ret.
Вот такой путь. почти всё работает, еще не отладил до конца =)

Сообщение отредактировал RLC - Dec 12 2017, 12:29
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 13:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01404 секунд с 7
ELECTRONIX ©2004-2016