Спасибо !
Назвал "Spindle RPM and actuator tester". Как яхту назовёте так и поплывёт :)
На экранчике платы называется просто ">> Скорость <<", в web-интерфейсе будет какое-то развёрнутое название.
--
По софту есть три больших вершины, которые нужно достичь:
1) Переходим от моделек к чистовым прогам. Нужна система сборки (Makefile) и хорошие архитектурные решения по части раскидывания общих функций по библиотекам.
В основном ПО Моста3 повторяет ПО Моста2, но творчески.
clock - прога, проверяющая часы теперь будет называться sram-check, она проверяет ОЗУ семплера, ну и тут же можно сделать проверку кварца семплера. Её пока нет в чистовом виде, но есть в виде черновика, пока без проверки кварца.
Тут некоторая заморока в том, что я стал докапываться насчёт низкой скорости обмена с семплером и выкопал следующее:
Всё таки сам SPI-контроллер работает на 30 МГц и всё норм. Не норм в том, что само обращение к стеку драйверов весит прилично по времени. Кроме того, судя по исходнику верхнего же драйвера в стеке, там есть некоторые лишние действия: ядро сперва получает данные в память контроллера SPI, потом тащит их в основное ОЗУ ядра, потом перекладывает оттуда в ОЗУ программы. Получается не быстро. Даже оптимизация обращения к драйверу (больше данных за обращение - примерно 60 слов вместо 15) уже позволила приподнять скорость раза в 1.5. Но этого мало. Есть мысль, что ещё можно улучшить пару мест: в драйвере верхнего уровня сразу предусмотреть первый слой раскодирования - чтобы в мою прогу шли уже интервалы, а не голые выборки; и кроме того попытаться распараллелить получение данных из памяти контроллера в память ядра и первый слой раскодирования. Сейчас на время получения данных из контроллера поток исполнения просто стопится.
И всё же прога "скорость" у меня уже почти в чистовом варианте. Она работает, выводит на консоль и на индикаторы платы результаты.
Причем я объединил в одну две программы моста2: pos и speed. Т.е. она одновременно измеряет скорость и позволяет двигать головку. Пока измерение только для 840-ки, по сигналу индекса. В дальнейшем её нужно будет расширить на случай 140ки и измерений по интервалам между адресными полями - в 140ке сигнала индекс нет.
По итогу работы над ней кристализовались несколько библиотек:
- GPIO - управление дискретными линиями проца через новый интерфейс ядра gpio-chip. Это управление не через /sys/class/gpio, как было до 5-го поколения ядер, а через /dev/gpiochipX. В общем-то, немного ровнее код тут получается, и - что для меня важно: для входящих линий ядро делает пометку о точном времени события (т.е. когда линию дёргают снаружи). Для проги Скорость это даёт хорошую точность измерений по индексу. Замер по адресным полям в этом уже не особо нуждается - там вся точность определяются точностью генератора семплера.
- drive_control - всё управление флопиком: включить/выключить, подвинуть голову (вправо, влево, на нужную дорожку, на ноль) и всё такое прочее. Насколько возможно, эта библиотека нивелирует разницу между управлением 140кой и 840кой.
- err_proc - всякие мелочи по самоконтролю программ, отладке, assert() и всё такое.
- term - управление прогой во время её работы из консоли: т.е. например: Скорость считает периоды, но я хочу сдвинуть головку: я нажимаю стрелку и прога, не прерываясь, что-то двигает головой. В реалиях юниха на это нужно немного дополнительных действий, так как терминал, обычно, настроен на то, чтобы работать со строками, а не отдельными кнопками. А мне нужны не только кнопки с консоли, но и клавиатуры, размещённой на самом устройство. Плюс к тому, для работы с web-интерфейсом прога тоже должна иметь какой-то простой механизм взаимодействия с браузером.
Да, есть библиотека ncurses, которая решает всё по консольной клавиатуре и экрану, но я опасаюсь, что её применение усложнит режим работы прог в качестве бекэнда для web-режима.
- UI-server и UI-client. Это механизм для удобного управления пользовательским интерфейсом платы. Т.е. сюда включаются как драйвера контроллеров LED, OLED, клавиатуры так и механника удобного использования всего этого добра из конечных программ. Примерно так:
ui_printf("LED8:%4d", track) - и переменная track сразу улетает на крупый дисплей.
или так:
ui_printf("OLED:\\6l\\0pПериод: \\i%6.2f мс\\i ", (double) delta / 1000000);
Выводит в строку 6 позицию 0 OLED-дисплея строку "Период: 199.56 мс", причём цифра выводится в инверсии.
Шрифт, само собой, агатовский.
Эта механника может использоваться как из C-шных прог так и из sh-скриптов, которые будут работать с пользовательским интерфейсом при запуске устройства, настройке в полях и, собственно, запускать пользовательские проги.
Можно сказать, что эта первая вершина достигнута.
2) Вторая вершина - это также начать чистовик web-интерфейса. Пока у меня был готов только примерный дизайн, сейчас уже надо переходить к его движку. Именно сейчас, потому что если для его работы потребуются какие-то доработки прог, то проще дорабатывать одну Скорость, чем потом всё остальное.
Поскольку web-интерфейс должен быть активным, то есть в реальном времени отрисовывать результаты работы прог и позволять немного управлять ими (остановить, пропустить данный трек, ....) то нужно два канала связи: от web к плате и от платы к web.
Протокол HTTP пилился не для интерактива и всё, что было доделано потом для интерактива рядом с HTML - в том или ином ракурсе очень напоминает костыли. Пока их три: AJAX - который умеет оба направления, но только по запросу браузера, Server Side Event - который умеет только от сервера к браузеру, зато по запросу сервера и Websocket, который умеет в обе стороны, по запросу любой стороны, но использует уже не чистый HTTP, а его расширение, которое должен поддерживать сервер.
Сервер я расширять/писать свой или вкручивать готовый на node.js не хочу ибо лень копаться. Поскольку нагрузка на web-сайт у нас хорошо предсказуема, обойдусь, для начала AJAX'ом: опрос сервера раза 4 в секунду должен дать хорошую возможность как отправить нажатия кнопок от браузера на плату, так и забрать новые результаты. НО ! Если результатами будет полотно из информации о каждом прочитанном треке, то к конца съёма диска оно будет достигать уже нескольких килобайт и гонять их 4 раза в секунду будет, возможно, не очень хорошо. Тогда будет логичнее AJAX оставить только для управления web-> плата, а плата-> web всё таки отправлять через SSE - там хорошо ложится логика "отправлять только дополнения, а не всё каждый раз".
Но для SSE нужна несколько более сложная обёртка, которая отправляет сперва всё, что есть, а потом следит за появлением новой информации и отправляет только её.
В общем: это примерно те вопросы, которые предстоит решить, чтобы считать вершину 2 достигнутой.
Когда она будет достигнута, можно будет снимать следующее видео.
3) Вершина три: это архитектура единой проги, которая будет читать и декодировать трек.
Сейчас у меня, фактически, три программы: одна формально читает RAW, преобразует его в массив интервалов между импульсами, вторая делает умный вид и синтезирует пять/десять/пятнадцать файлов байтового потока, различающихся настройками алгоритмов декодирования, затем стоит EimEditor, который из байтового потока собирает сектора и - наконец-то - может проверить их контрольные суммы. Это всё нужно согнать в один код, который будет прогонять данные по какой-то одной ясной цепочке и, только если не получит правильные CRC, будет пытаться изменить свои настройки и пробовать ещё раз.
Самое сложное всегда: продумать архитектуру. Её приходится, буквально, нащупывать. Сперва придумать хоть что-то, реализовать это, убедится, что тут чего-то ещё не хватает, опять переделать всё и так раза два-три, пока не всё не начнёт становится красивым. Если всё выглядит красивым, скорее всего, оно правильно. Пока что.
--
Итог на сегодня:
1) От моделек перешёл к чистовикам. Прога Скорость, работает и выглядит как настоящяя. Плюс несколько полезных библиотек.
2) Перепробовал несколько микрух контроллеров LED- у всех баг с кнопками, о котором я ранее писал. Поскольку эту уже вторая существенная ошибка в плате (первая была в питании Ethernet), то дело явно идёт к тому, что по завершению разработки ПО второй экземпляр устройства будет уже на новой плате.
3) Запаял несколько регуляторов 12->5v, всё ок, работают (нужны на случай питания платы только от +12в). И к ним ещё пару разъёмов питания.
4) Запаял UART-USB конвертор, работает хорошо, но нужен только для удобной отладки ПО (до этого пользовался внешним).
5) Запаял USB-разъём для флешек. Потом пару дней искал, почему он не работает. Оказалось: одну настройку в ядре пропустил. USB поддерживается стеком, включающем два драйвера физических компонент: MXS_PHY (от FreeScale уровень физического интерфейса) + CHIPIDEA (похоже, FreeScale лицензировал готовый IP-блок - это уровень какой-то внутренней USB-логики). Вот MXS_PHY у меня был, а CHIPIDEA - нет. Вроде как USB cтартует, загружается обобщённый драйвер USB, но лапы снаружи проца висят в Z-state и ничего не хотят.
<6>[ 0.133709] usbcore: registered new interface driver usbfs
<6>[ 0.133828] usbcore: registered new interface driver hub
<6>[ 0.134012] usbcore: registered new device driver usb
<6>[ 1.127870] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
<6>[ 1.140567] usbcore: registered new interface driver usb-storage
--- до сюда доходил и всё ---
<4>[ 1.150150] imx_usb 2184000.usb: No over current polarity defined
<4>[ 1.156422] imx_usb 2184000.usb: 2184000.usb supply vbus not found, using dummy regulator
<3>[ 1.776949] mxs_phy 20c9000.usbphy: Data pin can't make good contact.
<4>[ 1.785970] imx_usb 2184200.usb: 2184200.usb supply vbus not found, using dummy regulator
<6>[ 1.803654] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1
<6>[ 1.839165] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00
<6>[ 1.844950] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
<6>[ 1.853310] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[ 1.860597] usb usb1: Product: EHCI Host Controller
<6>[ 1.865501] usb usb1: Manufacturer: Linux 5.4.3-g9c2490ac8-dirty ehci_hcd
<6>[ 1.872345] usb usb1: SerialNumber: ci_hdrc.1
<6>[ 1.878016] hub 1-0:1.0: USB hub found
На картинке: прога выводит два интервала: мгновенный (последнего оборота) и усреднённый по всем оборотам.
По усреднённому видна интересная тенденция: по мере прогрева флопика скорость немного растёт (где-то в сотых мс).
Post's attachments
DSC_5034s.jpg 128.41 kb, 126 downloads since 2022-11-04