-
Постов
1 610 -
Зарегистрирован
-
Посещение
-
Победитель дней
2
Весь контент juvf
-
т.е. нужно задать клоки для ЦАП так? create_generated_clock -name {clkDac} -source [get_pins {pll|clk_in[0]}] -duty_cycle 50.000 -phase 90.000 -master_clock {clk1} [get_ports {clkDac}] тестовый проектик попробую выдернуть из проекта попозже.
-
А где неправильно? Я ваши статьи до дыр зачитал... ни чего не понятно. По вашим картинкам и по вашему тексту вроде всё понятно. У меня совершенно другие картинки в TQ. На моем рисунке начало анализа не понятно от куда. Вышел Lautch Clock из плл (самая верхняя кривая), после этого этот клок должен прийти на вход ОЗУ, очевидно что будет какая-то задержка.... 1...2 нс. Но у меня задержка клока -3.474 нс (Clock Delay). Почему МИНУС 3.47? Далее .... после того, как клок прошел задержку в МИНУС 3.47нс идет задержка 6,243 нс на доставку данных к порту плис (Data Delay). констрейны create_generated_clock в TQ автоматом создал. Там что-то неправильно? Что нужно констрейнить и относительно чего? На самом деле мне нужно чтоб на НОЖКЕ плис clkDAC сигнал не убегал относительно данных на НОЖКАХ плис Dout. Как Doun или clkDAC убежит относительно входного клока ПЛИС или выходных регистров PLL - неважно. Из TQ попытался сделать set_max_delay -from [get_ports {Dout[*]}] -to [get_ports {clkDac}] 7 так проект вообще не собирается в квартусе. ps Вопрос по вашей статье.....часть4 Это вы задали допуски для ...... для выхода data[*] модуля dac относительно выхода oclk модуля dac. А как же задержка прохождения от выхода data[*] модуля dac до конкретного пина плис? Или она не констрейница? Почему в TQ время Clock Delay в Data Required отрицательное?
-
Помогите с констрейнами
juvf опубликовал тема в Работаем с ПЛИС, области применения, выбор
на рисунке 2 схема управления внешним ЦАП. На рисунке 1 времянка из даташит на АЦП. Как правильно задать констрейны не учитывая внешних задержек (в плате все цепи выравнены). в *.sdc файле описал клоки. set_time_format -unit ns -decimal_places 3 create_clock -name {clk1} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk}] create_generated_clock -name {pll|clk_out[0]} -source [get_pins {pll|clk_in[0]}] -duty_cycle 50.000 -master_clock {clk1} [get_pins {pll|clk_out[0]}] create_generated_clock -name {pll|clk_out[1]} -source [get_pins {pll|clk_in[0]}] -duty_cycle 50.000 -phase 90.000 -master_clock {clk1} [get_pins {pll|clk_out[1]}] не могу понять как описывать выходные пины Dout и clkDac? Очевидно нужно описать выходные задержки, но между чем и чем? мне нужно чтобы передний фронт clkDac был посередине установки данных на Dout. По даташиту, при моих частотах допускается передний фронт clkDac двигать ±2 нс относительно Dout. Как это правильно прописать в констерейнах? пробовал так set_output_delay -clock [get_clocks {pll|clk_out[0]}] -max 7 [get_ports {clkDac}] set_output_delay -clock [get_clocks {pll|clk_out[0]}] -min 3 [get_ports {clkDac}] set_output_delay -clock [get_clocks {pll|clk_out[0]}] -max 2 [get_ports {Dout[*]}] set_output_delay -clock [get_clocks {pll|clk_out[0]}] -min -2 [get_ports {Dout[*]}] такие констрейны не выполняются. Например по clkAdc такие картинки - рисунок 3. Не понятно по графику.... по идее клок pll|clk_in[0] испустился (Launch Clock), через 5 нс ±2 должен появится клок на выходе плис clkDac (Latch Clock). Но на графике всякие Clok Delay и Data Delay почемуто ДО того, как испустился клок (Launch Clock). Кто-нибудь может пояснить эти диаграммы, плииз. -
Пробуйте трассировку. Как минимум трассировку в буфер, или сразу с помощью макросов трассировки. Подробно процесс трассировки описан в КиТ №11 2011 Можно определить макросы по входу и выходу задачи, на тик, на изменение приоритета, а также если запись по xQueueSendFromISR провалилась.
-
нашел в спартанском качестве :laughing: FreeRTOS_part_10.7z
-
а как вы делаете? понятно что вы кеш отключаете. а что дальше? как изменить 1 бит в GPIO без макрасов IOWR/IORD? *((alt_u32*)(PORTB_BASE)) |= (1 << MODBUS_1); такой код выставит битик с номером MODBUS_1 на GPIO по адресу PORTB_BASE, не затрагивая другие?
-
+1. Я вообще удивлён, что этого не сделано до сих пор.
-
Nios II, порт ...\FreeRTOS\Source\portable\GCC\NiosII Ага, спасибо..... нашел вот что: extern void vTaskSwitchContext( void ); #define portYIELD() asm volatile ( "trap" ); #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext() Только что за xSwitchRequired? В принцепе в моем случае я уже проверил что переключение требуется и можно смело вызывать напрямую vTaskSwitchContext(). Хотя наверно элегантнее будет проверять так void UartPC::uartInt(void *context)//прерывание по RS-232 от bawdc { static alt_u8 byte; static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; alt_u16 status = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE); if(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) {//прерывание по приему byte = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE); xQueueSendFromISR(uart232Queue, &byte, &xHigherPriorityTaskWoken); } portEND_SWITCHING_ISR(xHigherPriorityTaskWoken == pdTRUE); } ps Наверно для некоторых платформ нельзя. В статьях КиТ по фрииртос (№7 стр 26) сказано про переключение контекста в прерываниях....
-
Как переключаться на другую задачу после прерывания? есть фоновая задача, мигает лампочкой. есть более приоритетная задача для работы с UART. Задача для уарта ждет появления байта в очереди void taskRS232(void *pvParameters) { alt_u8 byte; for(;;) { xQueueReceive(uart232Queue, &byte, portMAX_DELAY); handler232(); } vTaskDelete( NULL ); } посылаю в устройство байт. попадаю в прерывание по приему. в конце прерывания проверяю нет ли более приоритетной задачи чем прерванная и если есть то переключаю контекст void UartPC::uartInt(void *context)//прерывание по RS-232 от bawdc { static alt_u8 byte; static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; alt_u16 status = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE); if(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) {//прерывание по приему byte = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE); xQueueSendFromISR(uart232Queue, &byte, &xHigherPriorityTaskWoken); } if(xHigherPriorityTaskWoken == pdTRUE) taskYIELD(); } задача ожидавшая появление в очереди uart232Queue байта разблокируется и начинает работать. После обработки ожидает следующий байт в очереди. Почему то попав в ожидание xQueueReceive(uart232Queue, &byte, portMAX_DELAY) после taskYIELD() управление задаче по миганию лампочки не передается. выполняется пустая задача. мигание лампочки в состоянии блокировки. Убрал из обработчика прерывания переключение контекста taskYIELD();. Всё заработало, но медленно. видно что после прерывания задача уарта не сразу получает управление, наверно по тикам. Дальше стал ковырять исходники и нашел vTaskSwitchContext(). Вставил в конце обработчика прерывания vTaskSwitchContext() вместо taskYIELD() - всё заработало как надо. переключение происходит сразу по выходу из обработчика-прерывания. Что за функция vTaskSwitchContext()? Как правильно ею пользоваться? Почему taskYIELD() блокирует прерванную задачу? Как правильно сделать так, чтоб при выходе из обработчика прерывания управление передавалось не прерванной задаче, а задаче готовой к выполнению с самым большим приоритетом?
-
а чё за баш? в прицепе у меня сейчас командный файл (*.bat), который находит файл проекта build.h, и в нём модифицирует определение #define BUILD 1234 потом в проекте я этот дефайн использую. получается что номер сборки зашит в код. на баше наверно тоже самое, тока под *nix
-
Спасибо за "Nios II Application Properties". Поиск не дал ни чего. Думаю можно руками к каком-нибудь *.h фале сделать #define DEBUG, а потом батником перед(после) сборки проверять - есть ли это определение, если есть, то не инкреметировать минорную версию.
-
Не нашел в свойствах проекта где этот ON и уровень оптимизации. В bsp редакторе есть уровни оптимизации, а вот где в свойствах проекта это всё? ну и до кучи вопрос..... хочу во первых включить в код отладочную информацию, например #ifdef DEBUG sprintf("error code 1234"); ledOn(RED); #endif какой define нужно проверять, что бы понять что сборка дебажная во вторых: .... сейчас в свойствах bsp указал запуск батника перед сборкой, который увеличивает номер сборки. Для релизов хочу запускать другой батник, который будет увеличивать минорный номер релиза. как запускать разные батники для разных сборок?
-
Возможно уже была тема..... Как в эклипсе собирать дебажную и релизную сборки для NIOS?
-
там где при получении флага нужно его сбросить, так и делаю. но, чем отличается флаг от семафора? тем что один поток один раз выставляет флаг, а второй получая его может сбросить, а может не изменять. получатель флага крутится в своем вайле, ждет флаг в блокировке. другой поток единожды выставил флаг, т.е. грубо говоря выставил "1" на порт EnabledTransmit, второй поток увидел что флаг стоит, т.е. ему разрешили работу и вышел из блокированного состояния. выполнил работу, проверил ещё раз флаг, ага, всё ещё стоит, значит ещё раз выполню работу. И так 2-ой поток выполняет одну и туже задачу до тех пор, пока первый поток не сбросит флаг в ноль. В freertos есть подобие флагов - это двоичный семафор. Но второй поток прочитает его один раз и семафор(флаг) сбросится. Можно ли в freertos захватить семафор не уничтожая его в очереди? Бывает что один флаг ждут 2 потока. Если делать на семафорах придётся 2 семафора заводить.
-
наверно можно и так.... операции чтение и запись - атомарные. но только каждый флаг будет в отдельной переменной. ...... просто портирую с uC/OS в FreeRTOS. в микроси есть флаги. Один поток в нужный момент выставляет флаги, 2-ой поток ждёт когда встанут(сбросятся) нужные флаги, т.е. 2-ой поток будет находится в блокированном состоянии до того, пока флаги не установятся. С volatile-переменной придется как-то в вайле с паузой проверять эту(эти) переменную(ные). или в отдельном потоке организовать проверку флагов и высылку события...... чё-то как-то всё сложно :(
-
А как флаги делать в FreeRTOS? Например один поток после определённых действий выставил флаг, второй читает. Если флаг выставлен в "1", то второй поток выполняет действие, потом опять проверяет флаг, если в 1, то ещё раз действие и т.д. В FreeRTOS не нашел флагов. можно с помощью костыля флаг в фрииртос организовать..... завести глобальную переменную типа bool и оградить к ней доступ через мютекс. А можно как-то по проще и элегантней это сделать?
-
Ой..... не 150, а половина. т.е. 75. Когда ддр работал 200, ниос работал на 100 МГц. Слона и не заметил. Раскрыли глаза. Не проходил клок от ддр и от лвдс по моим самописным блокам. В блоках было много последовательных операторов "=". Подправил на "<=" и в мегакорке altsqrt была задержка 1 такт. Сделал 5. Ошибки исчезли. Спасибо!!!
-
сори, это только в понедельник смогу входной клок 50МГц. Ддр работает на 150 МГц. Ниос тоже от 150 работает. У меня получалось запускать ддр на 200 МГц, без проблем вроде работал. правда не помню были тайменги или нет. так то нареканий на работу ддр нет. Но сам проект.... не с того не с сего какой-нибудь регистр совершенно в другом месте, в моих модулях, встает в 1. Или данные с лвдс приходят так, что биты 13 и 10 залеплены на 1. Проц работает, программа работает, а какой нибудь модуль не работает. Пойду, на кофейной гуще погадаю..... Ни чего не меняю в проекте.... Пересоберу проект ....... ОООО!!! Работает. Еще раз пересоберу - не работает. И постоянно крики таймквеста. А с криками проект работал устойчево? или глючил? ps у меня DDRII
-
Собрал проект на CycloneIII c Nios-ом. В ниосе есть ддр контроллер и lvds приемник. При компиляции критические ошибки. Не проходит анализ тайменгов по контроллеру ддр и лвдс. ДДР - контроллер альтеровский, ЛВДС - это тоже альтеровская корка. В констрейнах прописано: set_time_format -unit ns -decimal_places 3 derive_clock_uncertainty create_clock -name {clk1} -period 20.000 -waveform { 0.000 10.000 } [get_ports {clkADC}] create_clock -name {clk2} -period 40.000 -waveform { 0.000 20.000 } [get_ports {clkFPGA}] Почему тайменги не проходят и как с этим бороться? В какую сторону идти? Может надо как-то хитро констрейны прописывать?
-
Спасибо тебе добрый человек!!! Заработало! ps надо битик выставить на GPIO. пишу на си так alt_u32 portB = IORD_ALTERA_AVALON_PIO_DATA(PORTB_BASE); portB |= 1 << MODBUS_1; IOWR_ALTERA_AVALON_PIO_DATA(PORTB_BASE, portB); но идее можно обойти кеш и без альтеровских функций. если записать так: *((alt_u32*)(PORTB_BASE|0x80000000)) |= 1 << MODBUS_1; - это таже песня. по идее сначала в обход кеш значения прочитаются, потом выставиться в 1 бит MODBUS_1, и полученный результат запишится в порт?
-
нашел в чем была проблема. вроде шина заработала. но осталась одна проблема. сделал свой модуль, с которым ниос общается через параллельную шину. команда IOWR_16DIRECT(0x10013202, 0, 0x4); работает нормально. в нужное место прописывается 4. пробую так *((alt_u16*)0x10013202) = 4; - не работает. шагаю в дебаге по сишным строчкам... прохожу строчку *((alt_u16*)0x10013202) = 4;, все работает. снимаю точки останова запускаю программу - обращение через указатель не работает. посмотрел дизассемблер нашел разницу вот как компилятор скомпилировал код IOWR_16DIRECT(0x10013202, 0, 0x4); //IOWR_16DIRECT(0x10013202, 0, 0x4); 800bb70: 00c40074 movhi r3,4097 800bb74: 18cc8084 addi r3,r3,12802 800bb78: 00800104 movi r2,4 800bb7c: 1880002d sthio r2,0(r3) а вот как скомпилировал *((alt_u16*)0x10013202) = 4; //*((alt_u16*)0x10013202) = 4; 800b634: 00c40074 movhi r3,4097 800b638: 18cc8084 addi r3,r3,12802 800b63c: 00800104 movi r2,4 800b640: 1880000d sth r2,0(r3) разница в последней команде. с sthio - работает, а с sth. посмотрел в чем разница этих команд: как сделать чтоб обращение через указатель к нужным областям памяти не кешировались и не буферезировались, т.е. чтоб компилятор при обращении через указатель использовал команду sthio?
-
Ошибка в слове "имеет" в 6-ой части ps Можно ошибки указывать и в комментариях на статью, но там нужно логиниться, регистрироваться и т.п. Может разрешить коменты оставлять без регистрации? Или сделать механизм отправки ошибок как на некоторых сайтах, например на госуслуги.рф, выделяешь текст с ошибкой.... жмёшь CTRL+ENTER, коротко указываешь суть и сообщение об ошибке уходит автору ресурса.
-
эээ.....??? наверно глупый вопрос... а это где? )) Скачал ваш пдф с депозита, спасибо за сборку. Я бы ещё подрихтовал бы ваш документ. Электронный указатель(содержание), форматирование, рисунки... некоторый текст перекрыт разрывом страниц, некоторый текст вообще отсутствует и т.п. Не могли бы вы исходником пдф-а поделиться? можно на почту juvf | c06аka | yandex.ru
-
спасибо, кое что прояснилось в теории. Но теоретически лошадь, а практически упала. Как сделать параллельную шину. Как это делается практически? Открыл я твой компонент в Qsys. Что за сигналы lb и ub? Как изменить разрядность шины адреса? Как удалить не нужные сигналы? Так то у меня на этой шине ожидается 5..7 устройств. Я раньше брал и на старших адресах ставил дешифратор, на выходе которого получал чипселекты. Судя по альтеровской доке Avalon Tri-State Conduit Components User Guide можно сделать для каждого устройства свой тристэйт контроллер и через Tristate Conduit Pin Sharer посадить их все на одну шину с несколькими чипселектами. Такой вариант мне больше нравится. Но не получается. Как я делаю по "индусски": Требуется получить параллельную шину адресс, данные, и положительные сигналы чтения и записи. Добавил Generic Tristate Controller + Tristate Conduit Pin Sharer + Tristate Conduit Bridge. см рис. Скомпелял. Теперь пишу прогу. Как достучаться до памяти? пишу IOWR_16DIRECT(DAC1_BASE, 0, 0x100); - выполняю эту строчку и смотрю в сигналтабе сигналы своей параллельной шины. Сигналы не меняются. А на строке alt_u16 = IORD_16DIRECT(DAC1_BASE, 0); вообще прога виснет. Заходит в эту функцию и не выходит. Пробовал так alt_u16 = *(alt_u16*)(IORD_16DIRECT); Тоже на этом месте виснет. Как читать/писать в/из с параллельной шиной? Что я делаю не так?