Jump to content

    

RLC

Участник
  • Content Count

    66
  • Joined

  • Last visited

Community Reputation

0 Обычный

About RLC

  • Rank
    Участник

Информация

  • Город
    СПб

Recent Profile Visitors

682 profile views
  1. У нас программатора нет-иначе я бы проектировал устройство с необходимыми выводами на программатор. Поэтому пока что жду от них условий NDA
  2. Тсссс =) это нарушение закона об авторском праве. Ну и софтинка работает ведь с их программатором, поэтому надо еще знать внутреннюю архитектуру программатора. Если б там интерфейс был такой же как и на ПК то было бы проще а так...
  3. Да, действительно не понятно что тут тайну делать. Я бы понял если это была бы рос фирма с гос участием. Наши так "эффективно" работают, ну а Америкосы то что... Ну если в NDA будут запредельные требования то уйду к конкурентам =) А так как будто они хотят продать свой супер программатор на I2C.
  4. на оф форуме мне ответили: " We can suggest you to use our Clock Programmer software with Miniprog 3 to program the device. If you want to pursue programming with the help of the FPGA you will need the programming specifications for the device. For the specs you need to sign a NDA with Cypress. Thanks, Pradipta. " На русском: "Мы можем предложить вам использовать наше программное обеспечение Clock Programmer с Miniprog 3 для программирования устройства. Если вы хотите заниматься программированием с помощью FPGA, вам понадобятся спецификации программирования для устройства. Для спецификации вам нужно подписать NDA с Cypress." Поэтому вопрос не к форумчанам. Благодарю gosha-z за потраченное время
  5. Привет. Не слепой. её в документации нет. :( На оф форуме пока что вопрос тоже без ответа висит. ссылка на вопрос на оф. форуме.
  6. Добрый день форумчане. Вот ломаю голову как мне запрограммировать внешнюю PLL с ПЛИС по интерфейсу I2C. Может кто-то сталкивался с этой микросхемой и сможет подсказать. В моём проекте используется микросхема PLL Cypress CY27410FLTXI. Я хочу её запрограммировать через I2C интерфейс используя I2C master реализованный в FPGA . Данные конфигурации находятся в памяти FPGA. Для того что бы её запрограммировать мне необходимо записать по I2C 384 байт данных конфигурации (128 байт для области CM и 256 для Profile_0). I2C интерфейс позволяет адресовать только 256 байт. Подскажите, как мне запрограммировать CY27410FLTXI? 001-89074_CY27410_4_PLL_SPREAD_SPECTRUM_CLOCK_GENERATOR.pdf 001-94024_AN94024_GETTING_STARTED_WITH_CY27410_30_4-PLL_SPREAD-SPECTRUM_CLOCK_GENERATOR.pdf
  7. Цитата(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. Вот такой путь. почти всё работает, еще не отладил до конца =)
  8. Цитата(RLC @ Dec 4 2017, 08:58) Доброго всем дня. В процессе реализации данной задачи возник важный вопрос о передаче параметров (адреса возврата) в загружаемое приложение для возврата из него по окончании работы(по аналогии с возвратом из функции, но с использованием разного stack, heap, .rwdata, .rodata, .bss и тд). Пока что только одна идея-выделить в области памяти отдельную область для передачи параметров. Идея выглядит костыльной, хочется сделать через регистры процессора НО при загрузке нового загружаемого приложения вызывается код из файла crt0.s, который как раз устанавливает новую вершину стека. Вопрос: как можно самому поменять crt0.s, так что бы при перегенерации bsp он не возвращался к исходному,а всегда брался мною написанный? Есть конечно идея написать скрипт который будет генерировать bsp стандартным путём и потом подменять crt0.s, Но это опять же костыль. Кто может подсказать решение данной задачки? Путем чтения документации по процессу разработки, сборки, линковки ПО выяснил как можно создать и установить свой файл crt0.S. После прыжка на адрес загрузки, обозначенный как "_start" в map файле из регистров процессора можно взять необходимые адреса возврата и вершины стека. Делюсь с сообществом как это можно сделать. Самое главное это то что всё делается через makefile приложения(не bsp) и его можно менять, правда в ручную не рекомендует альтера. Для этого она создала свои утилиты настройки этого файла. В makefile определена переменная CRT0-путь к файлу crt0.S в которой по умолчанию не присваивается значение. После ее объявления проверяется значение этой переменной и если значение не определено(а по умолчанию так и есть) то устанавливается путь на файл в bsp. Значение можно ручками поменять и оно не меняется если не запускается утилита nios2-app-generate-makefile.exe. Собственно это всё что нужно знать. Если подробнее по шагам: -------------------------------------- Порядок действия для добавления своего файла crt0.S: 1) Скопировать файл в рабочую директорию 2) С помощью команды nios2-app-update-makefile.exe --app-dir . --add-src-files crt0.S добавить файл в makefile 3) С помощью команды nios2-app-update-makefile.exe –app-dir . - -list-src-files проверить что добавление файла произошло 4) Добавить скомпилированный файл crt0.o из директории "obj/default/" в переменную CRT0 Makefile с использованием команды "nios2-app-update-makefile.exe –app-dir . --set CRT0 crt0.o" 5) Выполнить clean 6) Выполнить make build
  9. Доброго всем дня. В процессе реализации данной задачи возник важный вопрос о передаче параметров (адреса возврата) в загружаемое приложение для возврата из него по окончании работы(по аналогии с возвратом из функции, но с использованием разного stack, heap, .rwdata, .rodata, .bss и тд). Пока что только одна идея-выделить в области памяти отдельную область для передачи параметров. Идея выглядит костыльной, хочется сделать через регистры процессора НО при загрузке нового загружаемого приложения вызывается код из файла crt0.s, который как раз устанавливает новую вершину стека. Вопрос: как можно самому поменять crt0.s, так что бы при перегенерации bsp он не возвращался к исходному,а всегда брался мною написанный? Есть конечно идея написать скрипт который будет генерировать bsp стандартным путём и потом подменять crt0.s, Но это опять же костыль. Кто может подсказать решение данной задачки?
  10. Цитата(Golikov A. @ Oct 16 2017, 15:54) вроде бы вот здесь то что вам нужно... http://www.alteraforum.com/forum/archive/i...hp/t-15278.html Вроде бы тепло. Читаю, разбираюсь. Понятно что нужно копать линковщик. Спасибо за ссылку. Если появятся вопросы - задам. Всего доброго.
  11. Цитата(Golikov A. @ Oct 16 2017, 14:50) Вы напишите более глобальную задачу который вы стараетесь решить таким "изысканным" способом... Строго говоря всегда можно вызывать функцию по указателю, например. Или переписать загрузчик и не инициализировать "стек" чтобы это не значило... Технология описанная мной это лишь реализация устоявшейся на фирме технологии проверки и тестирования аппаратуры. Тоесть программа HOST_PROGRAMM необходима для загрузки тестов для отладки и проверки работоспособности аппаратуры по ТУ. Соответственно LOAD_PROGRAMM это тесты различных аппаратно-программных контроллеров и программки для настройки и отладки при разработке. Соответственно с стеком ситуация следующая: HOST_PROGRAMM работает и при выполнении своих функций записывает адрес возврата из вызываемой функции. (pop, push). В какой то момент ей приходит команда о вызове функции по адресу(который приходит по RS-232 от пользователя) программы LOAD_PROGRAMM. Если это адрес main() LOAD_PROGRAMM то проблем нет и стек с адресом возврата сохраняется. После завершения main() происходит возврат в HOST_PROGRAMM. А если мы передаем адрес jump указывающий на crt0 LOAD_PROGRAMM то перед вызовом main() произойдёт запись другого адреса вершины стека и адрес возврата потеряется. Извините за описания возможно очевидных для вас вещей, просто хотел объяснить что я имею ввиду. Мне требуется для вызова main() всегда использовать один и тот же адрес и через стек возвращаться из LOAD_PROGRAMM в HOST_PROGRAMM. Последнее реализовано а вот как main() для любой программы-теста привязать к определённому адресу не знаю и поэтому спрашиваю у вас. Цитата(iosifk @ Oct 16 2017, 14:56) В ПЛИС можно сделать страничную память. Для каждой загружаемой задачи - свою страницу. Тогда у них у всех будет один и тот же адрес. Ну а переключение страниц - это уже отдельный вопрос... Дело в том что необходимо что бы технология работала и на NIOS II эконом без всяких дополнительных аппаратных блоков в ПЛИС. А память зачастую будет использоваться SRAM (ONCHIP).
  12. Добрый день. Есть задача, подскажите инструмент и технологию с помощью которой её можно решить. Описание существующей системы: Есть модуль с ПЛИС в которой реализован процессор 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 в ПО? Что в этом мне может помочь? Можно это сделать линковщиком? Спасибо за уделённое внимание.
  13. ВОПРОС про usleep(1000); Эта функция-задержка на 1мс(1000 мкс). Вопрос: во время этой задержки процессор будет обрабатывать настроенные ранее прерывания? В докуменнтации описано что не поддерживает ISR.
  14. Цитата(RLC @ Mar 30 2017, 11:50) Добрый день, форумчане. Возникла проблема с временем срабатывания таймера interval timer. Задача состоит в использовании таймера как счётчика времени в 40 мс и по прошествии этого времени выполнять некоторые действия. После этого остановить таймер и запустить через некоторое время( не известное точно но не ранее чем в 700 мкс). Кроме этого таймер может использоваться для других нужд, с другими временными интервалами, которые настраивать программно было бы приоритетно. Для этого таймер настроил на срабатывание каждые 1 мс и использовал функцию alt_alarm_start();. Однако при тестировании обнаружил что время реагирования на прерывание допустимое ( 170-180 мкс), а время выхода из прерыания более чем 0,3 сек. Вопрос: это нормально, что такое большое время возвращения из прерывания или я что то не корректно делаю? Для наглядности прикладываю скрин сигналтап с частотой синхронизации в 400КГц и памятью в 128КБ, исходный код тестового приложения которое инвертирует значение светодиодов при каждом срабатывании и настройки таймера и bsp. использую Quartus 12.1 NIOS II full с кэшем данных и кэшем инструкций. Использую в качестве контроллера прерывания IIC. Код/*--------------------------------------------------------------------- *                        START TIMER *    nticks-количество тиков после которого срабатывает функция callback * callback- функция обработчик. ----------------------------------------------------------------------*/ void start_timer(alt_u32 nticks,alt_u32 (*callback) (void*)){      if(alt_alarm_start (    &my_alarm, nticks,callback,(void*)0)<0){          uart_printf("\nNo system clock available\n ");      } } //----------------------------------------------------------------------- /*--------------------------------------------------------------------- *                        ОБРАБОТЧИК ПРЕРЫВАНИЯ ----------------------------------------------------------------------*/ alt_u32 handler_timer_irq(void* i){     alt_u32 led=IORD_32DIRECT(LB_MPVS_AVALON_SLAVE_TRANSLATION_BASE,0x48);     IOWR_32DIRECT(LB_MPVS_AVALON_SLAVE_TRANSLATION_BASE,0x48,~(led));     alt_u32 tick=alt_ticks_per_second();     return tick; } //----------------------------------------------------------------------- int main(){     start_timer(1,handler_timer_irq);     while (1){}     return 0; } В общем я решил задачу написав собственный драйвер для блока interval timer от Altera. Причина описанного поведения встроенного драйвера мне не ясна. К сожалению времени на выяснение причин у меня нет. В связи с этим тему можно закрыть, тк задача выполнена.
  15. Добрый день, форумчане. Возникла проблема с временем срабатывания таймера interval timer. Задача состоит в использовании таймера как счётчика времени в 40 мс и по прошествии этого времени выполнять некоторые действия. После этого остановить таймер и запустить через некоторое время( не известное точно но не ранее чем в 700 мкс). Кроме этого таймер может использоваться для других нужд, с другими временными интервалами, которые настраивать программно было бы приоритетно. Для этого таймер настроил на срабатывание каждые 1 мс и использовал функцию alt_alarm_start();. Однако при тестировании обнаружил что время реагирования на прерывание допустимое ( 170-180 мкс), а время выхода из прерыания более чем 0,3 сек. Вопрос: это нормально, что такое большое время возвращения из прерывания или я что то не корректно делаю? Для наглядности прикладываю скрин сигналтап с частотой синхронизации в 400КГц и памятью в 128КБ, исходный код тестового приложения которое инвертирует значение светодиодов при каждом срабатывании и настройки таймера и bsp. использую Quartus 12.1 NIOS II full с кэшем данных и кэшем инструкций. Использую в качестве контроллера прерывания IIC. Код/*--------------------------------------------------------------------- *                        START TIMER *    nticks-количество тиков после которого срабатывает функция callback * callback- функция обработчик. ----------------------------------------------------------------------*/ void start_timer(alt_u32 nticks,alt_u32 (*callback) (void*)){      if(alt_alarm_start (    &my_alarm, nticks,callback,(void*)0)<0){          uart_printf("\nNo system clock available\n ");      } } //----------------------------------------------------------------------- /*--------------------------------------------------------------------- *                        ОБРАБОТЧИК ПРЕРЫВАНИЯ ----------------------------------------------------------------------*/ alt_u32 handler_timer_irq(void* i){     alt_u32 led=IORD_32DIRECT(LB_MPVS_AVALON_SLAVE_TRANSLATION_BASE,0x48);     IOWR_32DIRECT(LB_MPVS_AVALON_SLAVE_TRANSLATION_BASE,0x48,~(led));     alt_u32 tick=alt_ticks_per_second();     return tick; } //----------------------------------------------------------------------- int main(){     start_timer(1,handler_timer_irq);     while (1){}     return 0; }