Jump to content

    

shamrel

Свой
  • Content Count

    157
  • Joined

  • Last visited

Posts posted by shamrel


  1. Приветствую!

    Лаборатории запущены уже много лет, по ним занимаются студенты заочной формы. Когда стенды свободны они доступны всем желающим.

    Сейчас запущены следующие лаборатории:

    1. По электронике. Реальное железо, подключены ЦАП и АЦП. Простенькие лабораторные работы по исследованию диодов, транзисторов, полевых транзисторов. Клиентская программа на LabVIEW.

    2. Лаборатория по изучению микроконтроллеров. Плата с контроллером MCS51. На него направлена веб-камера. Можно удаленно через вебинтерфейс загрузить в него hex и посмотреть, что будет.

    3. Лаборатория с ПЛИС. Похоже на предыдущую, только плата с FPGA Cyclone I. Можно прошить и подрыгать ножками. Для совсем начинающих.

     

    Сейчас все это дело собирается модернизироваться, хотелось бы получить отзывы и советы.

     

  2. Да, но приписку, с указанием того, что нужно рассматривать выражение в комплексе, даже если оно и оператором условия, я бы добавил. Это стандартная gotcha. Не все такие педанты в типах констант, как вы :)

    Спасибо. Внес соответствующую поправку в статью.

  3. result = condition ? '0 : (pipa + popa); // unsigned too

    Действительно, при использовании оператора Condition, результат беззнаковый. Но это полностью соответствует правилу:

    Если хотя бы один из операндов имеет беззнаковый тип (unsigned), результат будет беззнаковым, независимо от остальных операндов и типа операции.

    Достаточно явно указать константе '0 ее знаковость, например, так 'sh0, и все станет на свои места.

    Я использую Verilog-2001, там так задать константу ( '0 ) синтаксис не позволяет, приходится явно указывать формат представления, а указав его, сразу становится понятно, знаковый он или нет.

  4. Может не нужно статьи писать?! :smile3046: А то потом читаешь и :crying:

    Не помню кто, но кто-то сказал: "Победа - это когда N раз упал и N+1 раз встал." ;)

    Статья -- прекрасный способ бороться с невежеством, в том числе и самого автора. Особенно хорошо если, работает обратная связь от читателя, а автор готов работать над замечаниями.

  5. Знаковое число в каком коде, в дополнительном или другом? Где такое суммирование "по жизни" встречается?

    В дополнительном. verilog-2001 дефакто использует дополнительное представление знакового числа, потому уточнять не стал. По жизни ... мало ли где. Мне приходилось отслеживать переполнение в сумматоре в задачах ЦОС. Статья носит учебный характер. Задача продемонстрировать основные принципы работы с знаковым типом в verilog.

    При суммировании в доп.кодах к операндам добавляют еще один знаковый разряд, если в сумме два знаковых разные, то здесь есть факт переполнения. Или что-то не так?
    Да, так. На этом принципе основан мой второй пример. Вопрос в том, какой метод лучше?
  6. Смотря по чем судить по количесву логики или тактовой частоте

    Количество логики в обоих случаях одинаковое. Там и там одно комбинационное устройство. И быстродействие одинаковое (я ошибаюсь?): в обоих случаях сигнал со входа должен пройти сумматор и логический элемент.

  7. Приветствую!

    Пишу статью для студентов по теме знаковой арифметики в ПЛИС. Возник вопрос, как с академической точки зрения корректнее описать флаг переполнения при суммировании знакового числа и беззнакового. По логике вещей можно утверждать, что произошло переполнение, если старший знаковый бит изменился вопреки знаку операндов и характеру операции. То-есть, при сложении двух положительных чисел результат тоже должен быть положительным. В этом случае код модуля получается такой:

     

    module adder (
    input			[3:0]	A,
    input	signed	[3:0]	B,
    output		[4:0]	Sum,
    output			overflow
    );
    assign   Sum = $signed({1'b0, A}) + B;
    assign overflow = ~B[3] & Sum[4];
    
    endmodule

    Но есть и другое решение, увеличить разрядность результата и переполнение проследить уже там:

    module adder (
    input			[3:0]	A,
    input	signed	[3:0]	B,
    output		[4:0]	Sum,
    output			overflow
    );
    wire sign;
    assign  {sign, Sum} = $signed({1'b0, A}) + B;
    assign overflow = sign^Sum[4];
    
    endmodule

     

    Как вы думаете, как лучше? Может быть есть другие способы?

  8. Какой дистрибутив используете?

    Чего бы я делал.

    1. Установил бы minicom и попробовал бы стать AT команды непосредственно с таргета.

    2. Попробовал бы настроить pppd. Что и как делает kppp мне не понятно. К графическим программам такого рода отношусь с недоверием.

    3. Если pppd не заработает, а сообщений его покажется недостаточно, то я бы открыл бы конфиг его с AT командами, и в ручном режиме через миником слал бы эти команды и смотрел, где он споткнется.

  9. Проблемы возникают когда у микросхемы нет раздельных выводов земли.

    А если у микросхемы есть раздельные выводы AGND и DGNG, не вижу проблемы - соединять земли на источнике питания.

    То-есть, вариант 2. Кестер не прав, или как раз тот случай, когда цифровой ток "существенный" и оставлять его на GND нельзя?

  10. Спасибо за подсказку, но похоже, это не то. Все на месте. Пробовал и /sbin/init ставить, и /bin/sh - все равно кернел паник.

    Нет, скорее всего речь не про то. Как я понял, krux, имел специальный скрипт предварительной инициализации (preinit). Это по сути опциональная штука.

    1. Покажите строку cmdline, которая передается ядру при старте.

    2. Другими методами (например загрузка из RAM диска) убедитесь, что на разделе UBI у вас валидная файловая система (rootfs).

  11. Приветствую. Тема старая.

    Есть и книжки фундаментальные, хотя бы от того же Уолта Кестера, в которых указывается, что ЦАП ставить нужно на аналоговую землю, правда с небольшой оговорочкой, если цифровые токи не существенные (о_О). И в форуме тема поднималась неоднократно, среди достойных:

     

    Разделение аналоговой и цифровой земель, какие принципы

    Разделение земли на аналоговую и цифровую

    Быстродействующие ЦАПЫ и развязка цифровой, и аналоговой земель. Как правильно?

     

    Высказано много противоречивых мнений. И, как я понял, единого правила нет, нужно смотреть частный случай.

    Мой частный случай такой. Имеется ПЛИС, которая управляет ЦАПом (AD9767, 14 бит, 125 MSPS). После ЦАП идут аналоговые усилители, для питания использован интегральный DCDC +-12В. Как быть с землями? При этом аналоговое питания для ЦАП хотел завести с цифрового по отдельной линии с общего LDO, развязав ферритовой бусой и емкостями. Напрашивается 2 варианта:

     

    1. Считать случай классикой по Кестеру, разделить полигоны, все выводы com у ЦАП посадить на AGND. Под цифровыми сигнальными линиями поверхность DGND. Соединить DGND и AGND в одной точке, скажем под DCDC. В этом случае, тяжело представить путь возвратного тока для аналогового питания DAC. Да и для цифрового тоже плохо представляю.

    2. Внимательно изучить datasheet на AD9767 и его AN-555 Evaluation Boa у увидеть, что полигоны разделены. Цифровые выводы DCOM на полигоне DGND, а налоговые на AGND. Но тогда вопрос, как и где соединять эти земли. Где брать питание для аналоговой части ЦАП, и как в такую схему встраивается DCDC? с DCDC проще, он с гальванической развязкой от входа и ему не требуется соединение AGND и DGND вообще. А те операционники, что от него питаются образуют самостоятельный контур.

    3. Плюнуть на всё и сделать один полигон GND. И пусть нам повезет!

     

    Спасибо.

     

  12. Там какой-то другой файл. В .sdc - файле я сам констрейны задавал вручную ...

    Вот и пропишите вручную.

    des00 скромничает, но вот отличный пример:

    TimeQuest для чайников. Часть 3 (Клоки как вас много)

  13. В качестве констрейна указана только "основная" тактовая частота. Этого недостаточно ?

    На сколько я понимаю, нет. И об этом вам должен был сказать в предупреждении Quartus.

     

    Следует для каждой генерируемой частоты прописать типа такого:

     

    create_generated_clock -name {как ее назовем} -divide_by 2 -source [get_ports {от какого клока деленая}] [get_registers {откуда берется}]

  14. Делаю так:

    Tools -> IP catalog -> Basic functions -> Clocks; PLLs and Resets -> PLL -> Altera PLL

     

    Дальше заполняю формы нужными мне параметрами, потом нажимаю кнопку "Finish". Quartus генерирует множество файлов, и среди них - код на VHDL. А кода на Verilog нету. Это можно как-то исправить ?

     

    Зачем это нужно ? Я хочу поделить частоту приходящего в ПЛИС тактового сигнала в 2, 3, 4 и 5 раз, и эти выходы использовать для тактирования различных узлов в проекте. Можно, конечно, получить эти сигналы с выходов счетчика, но мне кажется, что использовать PLL корректнее ...

    Простите, такой не скромный вопрос. А на последней вкладке Summary нужную галочку установить не забыли?

     

  15. Насколько я понимаю принцип работы журналирования (безотновительно UBIFS или какой-либо другой конкретной FS), при операции, допустим, стирания блока:

    1. в журнал записывается информация о планируемой операции;

    2. выполняется собственно стирание;

    3. после успешного завершения операции запись в журнале уничтожается, а блок считается чистым.

     

    ....

    Так что говорить "журнал - не панацея" без привязки к конкретной реализации я бы не стал...

    Интересно, применяется ли аналогичный подход (принятие решения о валидности данных на основании контрольного чтения) в jffs2...

    Согласен, реализация имеет огромное огромное значение. В данном случае проблема в ней.

    Подлость "нестабильных" бит, в том, что при первом после сброса доступе они ведут себя адекватно. В результате транзакция будет закрыта. UBIFS имеет оптимистичный поход к данным, она доверяет проверке памяти. То-есть, например, захотела стереть блок, внесла пометку в журнал, начала стирать. Когда уже все стерла, но не "закрыла" LEB, отключается питание. И после перезагрузки, высмотрев в журнале незавершенное действие, файловая система сканирует это блок, видит, что там все единицы (то есть память стерта) и делает запись в журнал о счастливом завершении. Нет, чтоб, наивной еще разок стереть. А в результате может образоваться область нестабильных бит, последующая запись в которую, приведет к порчи данных.

    Аналогично и при других операциях. UBIFS доверяет CRC и если все Ok, то не производит операцию повторно.

    На самом деле оптимизм в поведении файловой системы понятен. Работать приходится с памятью, у которой ограничено число циклов перезаписи, и по времени стирание идет гораздо дольше чтения.

    Разработчики знают о проблемах. Надуюсь на обновление.

  16. Понимаю эмоции ТС, но мне больше всего мешает в CoCoox (на базе Eclipse) задержка, возникающая после введения одного-нескольких символов. С увеличением объёма текста задержка увеличивается, и когда в программе больше 2000 строк, "замирание" достигает нескольких секунд. Как от этого избавиться?

    Смею предположить, что время затрачивается на контекстный индекс. То-есть, IDE ищет по всему проекту, как вам помочь, какое автодополнение предложить, какой класс, какая структура и прочее прочее.

    Рекомендую покопаться в настройках индексера (можно глобально, а лучше в свойствах конкретного проекта) и убрать от туда анализ лишних файлов.

  17. Сабж. Как отключить все то, что пытается ёклипсъ делать за меня. Скобки закрывать, скобки в циклах открывать и тд. Бесит люто бешено. Формальное издевательство! Как можно такой продукт выпускать вообще?

    Эклипс имеет открытые исходники. Возьмите их, исправьте то, что вам мешает и соберите для себя.

    А если по делу. То, заходите в настройки Window -> Preferences. Там убираете галочки с мешающих вам опций. Ищите вкладки связанные с ключевым словом "Editor".

    Если пишете на C/C++, тот С/С++ -> Editor

     

    P.S.: Намой взгляд, Eclipse -- одна из лучших IDE.

  18. Интересно, каким образом удалось убить FS, просто отключая питание. Вы что, использовали нежурналируемую файловую систему?

     

    UBIFS -- журналируемая. Но журнал не панацея. После того как в результате испытаний, связь между отключением питания и сбоем была однозначно (это по протоколу, сам я допускаю наличие другой проблемы) установлена, начали искать теоретическое обоснование. Нашли на сайте разработчиков UBIFS. Причина может быть в нестабильных битах

    Причины сбоев и потери информации в NAND

     

    Питание было отключено перед тем как работа со страницей памяти была завершена. После перезагрузки страница может быть прочитана корректно, но при повторном чтении можно получить ошибку ECC. Это происходит потому что появилось некоторое количество нестабильных бит, которые могут читаться корректно или не корректно.

    Отключение питания происходит в момент начала работы со страницей NAND. После перезагрузки, страница может быть прочтена корректно: считаются все единицы (0xFF), но иногда, после перезагрузки можно из этой области считать только нули. Кроме того, если потом опять записать эту страницу, иногда может возникнуть ошибка ECC. Причина – опять нестабильные биты.

    Отключение питания во время стирания блока. После перезагрузки, опять же, могут появится нестабильные биты, и данные в блоке становятся поврежденными.

    Питание отключается после того, как операция очистки блока была запущена. И опять же, после перезагрузки блок содержит нестабильные биты: или при чтении возвращает нули, или поврежденные данные, при попытке записать туда информацию.

    Во всех случаях, после аварийного отключения питания область памяти может быть прочитана корректно, в результате система журналирования не увидит подвоха. Но при последующим доступе к этой области данные могут быть повреждены. Количество таких «нестабильных бит» может быть больше, чем алгоритм ECC сможет скорректировать. Поэтому, ранее читаемые страницы становятся нечитаемыми, или наоборот, ранее нечитаемая страница может стать вдруг читаемой. Проблема усугубляется тем, что нестабильные биты могут возникнуть в журнале файловой системы, так как статистически, эта область NAND наиболее часто модифицируется.

     

    P.S.: Чего-то спойлер не работает.

  19. Большое спасибо за разъяснения. А можно ли, допустим, назвать пин UsbOnGpio, и потом с ним работать из линукса, не экспортируя его каждый раз и не вспоминая, что же такое у нас GPIO125 ?

    В Linux можно все, но не всегда целесообразно, а затраченные усилия, порой, не пропорциональны результату.

    В своей практике, я в ПО, будь оно на Си или на Bash, порты описывал просто константами. Если проект объемный, то делал конфигурационный файл с настройками.

    Если вам хочется рулить ножками руками из юзерспейса, то создайте скрипты.

    В большинстве своем, достаточно редко приходится работать с линиями через драйвер GPIO, обычно к линиям, подключены какие-либо устройства, это описывается в Device Tree, и в системе уже можно работать с драйвером устройства, а не GPIO.

    А вообще, если мне не изменяет память, посмотреть назначения GPIO можно где-то в /sys/kernel/debug/gpio . Считать файл, да распарсить.

  20. Действительно. Перед началом работы с GPIO из userspace, соответствующий вывод должен быть прописан в DTS. Это нужно для того, что бы ядро знало, что с этой ножкой нужно/можно работать через gpio-драйвер.

    Я это делаю так:

     

    usergpio_pins: pinmux_usergpio_pins {
    	pinctrl-single,pins = <
    
    		/*button*/
    		0x05C (PIN_INPUT_PULLUP | MUX_MODE7) 		/* SW1 gpmc_a7.gpio1_23 MODE7 */
    		/*Vif vif_12v_fixed*/
    		0x16C (PIN_OUTPUT_PULLUP | MUX_MODE7)		/* uart0_rtsn.gpio1_9 MODE7 */
    		/*3V3_plc vif_3v3_plc_fixed*/
    		0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)		/* mcasp0_aclkx.gpio3_14 MODE7 */
    
    	>;
    };

    Соответственно, потом указатель на usergpio_pins помещаю в секцию pinmux.

    Собственно, для процессора из примера MUX_MODE7 -- режим работы вывода процесса, соответствующий GPIO. Что такое PIN_INPUT_PULLUP и PIN_OUTPUT_PULLDOWN, думаю, понятно и так.

    Единственная проблема с адресом. Это нужно смотреть документацию на процессор. Причем, следует отметить, что используется не абсолютный адрес, о смещение относительно блока pinmux.

     

    Как работать с этим в userspace. Допустим, хотим вывести 1 в gpio1.9. (объявлен в примере).

     

    1. Инициализируем устройство gpio1.9:

     

    echo 41 > /sys/class/gpio/export

     

    Тонкий вопрос, как gpio1.9 превратился в 41 ?. В процессоре параллельные порты объединены в 32-битную шину. В обозначении gpio1.9 первая цифра "1" -- номер порта, вторая -- номер ножки в порту. Таким образом, абсолютный номер порта будет 32 + 9 = 41.

     

    2. Устанавливаем направление порта.

    После экспорта в директории /sys/class/gpio/ появляется директория gpio41. Там много чего интересного, но сейчас нам нужен файл direction. Записываем туда направление.

     

    echo "out" > /sys/class/gpio/gpio41/direction

     

    Понятно, что для входа, значение будет "in".

     

    3. Устанавливаем уровень.

    Теперь, через запись в файл value значения, мы управляем выводом:

     

    echo "1" > /sys/class/gpio/gpio41/value

     

    P.S.: в командах могут быть ошибки, под рукой нет боевой системы.

     

     

     

  21. Если под начальными настройками подразумевается возврат всей системы в исходное состояние, в котором оно было выпущено с завода, то напрашивается вариант хранить rootfs дважды: первая копия записывается на заводе и никогда не модифицируется, вторая копия - рабочая. Для возврата к начальным настройкам вторая копия переписывается первой.

    Для этих целей придумали каскадно-объединенное монтирование. Идея следующая: создаем «виртуальный» раздел из двух физических разделов на носителе. Один раздел содержит образ rootfs, доступный только для чтения, а во время работы операционной системы все изменения заносятся во второй раздел, который доступен для чтения и записи. Для каскадно-объединенного монтирования разделов использована вспомогательная файловая система UnionFS, AUFS или OverlayFS.

    В статье (ссылка в предыдущем сообщении) подробный пример и объяснение создание такого пирога по технологии AUFS.

     

    Как уже говорилось выше, происходит объединение двух физических разделов. Первый раздел, в который изначально записан образ рабочей КФС, доступен только для чтения (RO – read only), второй раздел, изначально пустой, служит для хранения изменений, соответственно, он доступен как для чтения, так и для записи (RW – read write). В терминах aufs первый и второй разделы называются ветвями (branch). Объединение ветвей происходит в процессе монтирования. В результате операционная система видит смонтированную область как единое целое. Доступ к данным осуществляется драйвером ядра. Запросы на чтение файла драйвер в первую очередь направляет к RW ветви; если данные там присутствуют, то выдаются они, если там данных нет, то файл читается из ветви RO. При записи, данные попадают в ветвь RW. При удалении файла, в ветвь RW добавляется метка о том, что данный файл был удален (создается соответствующий пустой скрытый файл с определенным префиксом в названии). Физически файл остается в ветви RO целым. Такой подход позволяет избежать операций записи в разделе с критической информацией. Кроме того, так как ветвь RO доступна только для чтения, появляется принципиальная возможность добавить дополнительный контроль целостности данных. Реализовать это можно средствами UBIFS, сделав создаваемый раздел статическим. Статический раздел доступен только для чтения и данные там защищены контрольной суммой (CRC-32).

     

    При необходимости отката, или в случае повреждения данных, просто форматируем раздел с ветвью RW.