2097
Нове життя старого синтезатора. Частина 2
Продовжувати історію старого вигорання синтезатора, в якому я спробую дихати нове життя, повністю замінивши залізо, відповідальне за створення звуку з синтезатором програмного забезпечення на основі мінікомп'ютера EmbedSky E8 з Linux на борту. Як часто справа, набагато більше часу проходив між виданням перших і других частин статті, ніж заплановані, але, тим не менш, ми продовжимо.
У попередній частині процесу вибору апаратної платформи для нової «браїну» синтезатора окреслено опис технічних характеристик розчину, процес складання необхідних бібліотек і проблем, які мали б зіткнутися в процесі. Тепер, як для заліза, ми побачимо, як влаштовується клавіатурна матриця синтезатора, а потім буде більше деталей, присвячених темі програмного забезпечення.
Клавіатура синтезатора дуже схожа на звичну клавіатурну матрицю, яка багато шанувальників мікроконтролерів вже підключені до їх Ардуїно. Для кожного ключа синтезатора вона забезпечує від одного (в найдешевших моделях) до двох (в об'ємі моделей) перемикачів. За допомогою двох суміжних перемикачів, одна з яких, при натисканні, закриває трохи раніше, ніж інші, мікроконтролер може визначити умовну силу, а також швидкість, при якій натискається ключ, щоб звук відповідного обсягу. Це виглядає так:
Діоди розміщуються на задній частині дошки, що запобігають зчитуванню пресованих ключів, одночасно натискаючи кілька клавіш. Ось фрагмент схеми клавіатурної матриці, яка показує ці два перемикачі та діоди, підключені до них:
7017774
Щоб відсканувати матрицю, мікроконтролер послідовно витягує стовпчики (відключення, позначені як N) до джерела живлення і перевіряє рівень на рядах (відключення, позначені B). Якщо рівень будь-якої лінії високий, то ключ, що відповідає чинному комбінації стовпців. Схема показує тільки частину клавіатури - всього 76 ключів на ній (13 рядків і 6 x 2 стовпчиків, що дає загальну 156 можливих варіантів при скануванні матриці і 25 мікроконтролерних штифтів. Скасування всієї клавіатури здійснюється кілька десятків разів на другий і неприпустимо до виконавця.
Мікроконтролер, відповідальний за сканування клавіатури, спочатку був 8-бітний однопрограмний мікроконтролер Hitachi HD63B05V0, що працює на 8 МГц і має 4 КБ ROM і 192 байтів пам'яті. На жаль, цей контролер не був операційним після того, як потужність, описана на початку першої статті. Але, навпаки, виявилося, що практично сумісно з укладеннями з контролером ATmega162 у мене є, що я замінив різання і пайки тільки 2 доріжки на дошці, один з яких є вихід RESET, який не був в одному місці, як HD63B05V0.
З цього ввімкнено контролер не дозволяв мені використовувати вбудований UART (звідси він був також на інших терміналах), я використовував цей односторонній (записати тільки) виконання серійного порту для виходу інформації про пресовані ключі. Крім того, мікроконтролер був заповнений завантажувачом TinySafeBoot, а також з використанням серійного програмного забезпечення, для можливості оновлення майбутньої прошивки. З Я вибрав Python + Qt5 як мову для швидкого розвитку програмного забезпечення високого рівня синтезатора, я також написав модуль Python для tinySafeBoot, який дозволяє читати і писати прошивку мікроконтролером AVR. Мікроконтролер AVR підключений до серійного порту UART1 на дошці EmbedSky E8 і працює на 3,3V напруги, щоб уникнути необхідності перетворення рівня.
Код прошивки для AVR No1(Н)(Н)
Модуль Python для TinySafeBoot
У попередній частині процесу вибору апаратної платформи для нової «браїну» синтезатора окреслено опис технічних характеристик розчину, процес складання необхідних бібліотек і проблем, які мали б зіткнутися в процесі. Тепер, як для заліза, ми побачимо, як влаштовується клавіатурна матриця синтезатора, а потім буде більше деталей, присвячених темі програмного забезпечення.
Клавіатура синтезатора дуже схожа на звичну клавіатурну матрицю, яка багато шанувальників мікроконтролерів вже підключені до їх Ардуїно. Для кожного ключа синтезатора вона забезпечує від одного (в найдешевших моделях) до двох (в об'ємі моделей) перемикачів. За допомогою двох суміжних перемикачів, одна з яких, при натисканні, закриває трохи раніше, ніж інші, мікроконтролер може визначити умовну силу, а також швидкість, при якій натискається ключ, щоб звук відповідного обсягу. Це виглядає так:
Діоди розміщуються на задній частині дошки, що запобігають зчитуванню пресованих ключів, одночасно натискаючи кілька клавіш. Ось фрагмент схеми клавіатурної матриці, яка показує ці два перемикачі та діоди, підключені до них:
7017774
Щоб відсканувати матрицю, мікроконтролер послідовно витягує стовпчики (відключення, позначені як N) до джерела живлення і перевіряє рівень на рядах (відключення, позначені B). Якщо рівень будь-якої лінії високий, то ключ, що відповідає чинному комбінації стовпців. Схема показує тільки частину клавіатури - всього 76 ключів на ній (13 рядків і 6 x 2 стовпчиків, що дає загальну 156 можливих варіантів при скануванні матриці і 25 мікроконтролерних штифтів. Скасування всієї клавіатури здійснюється кілька десятків разів на другий і неприпустимо до виконавця.
Мікроконтролер, відповідальний за сканування клавіатури, спочатку був 8-бітний однопрограмний мікроконтролер Hitachi HD63B05V0, що працює на 8 МГц і має 4 КБ ROM і 192 байтів пам'яті. На жаль, цей контролер не був операційним після того, як потужність, описана на початку першої статті. Але, навпаки, виявилося, що практично сумісно з укладеннями з контролером ATmega162 у мене є, що я замінив різання і пайки тільки 2 доріжки на дошці, один з яких є вихід RESET, який не був в одному місці, як HD63B05V0.
З цього ввімкнено контролер не дозволяв мені використовувати вбудований UART (звідси він був також на інших терміналах), я використовував цей односторонній (записати тільки) виконання серійного порту для виходу інформації про пресовані ключі. Крім того, мікроконтролер був заповнений завантажувачом TinySafeBoot, а також з використанням серійного програмного забезпечення, для можливості оновлення майбутньої прошивки. З Я вибрав Python + Qt5 як мову для швидкого розвитку програмного забезпечення високого рівня синтезатора, я також написав модуль Python для tinySafeBoot, який дозволяє читати і писати прошивку мікроконтролером AVR. Мікроконтролер AVR підключений до серійного порту UART1 на дошці EmbedSky E8 і працює на 3,3V напруги, щоб уникнути необхідності перетворення рівня.
Код прошивки для AVR No1(Н)(Н)
Модуль Python для TinySafeBoot
Імпортний серійний імпорт binascii імпортний структурний імпорт intelhex імпорт sys class TSB(object): CONFIRM = '!' REQUEST = '?' def_init_(self, port): самопорт = послідовний.self(порт, baudrate=self) self.flash" = 0 deflash(self): nothashion("Not page") defactivated"(page=activated(page=self(sport:2, self-checker.complex. REQUEST) в той час як само.addr < len(data): якщо прогрес не None: прогрес("write", self.addr, len(data))) само.порт.write(self. Сайт розроблено компанією universalweb.com.ua + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Як програміст для AVR, я вперше використовував програміст на основі програми Launchpad MSP430, з якого у мене є кілька штук, а потім це домашнє диво (який добре працює, до речі), дав шлях до програми TL866CS MiniPro, який прибув з Китаю. Відчуття нового програмера дуже позитивне.
Дуже докладно про пристрій клавіатури синтезатор і методи сканування, в тому числі один дуже оригінальний метод сканування через інтерфейс мікроконтролера AVR для підключення зовнішнього чіпа оперативної пам'яті описано на сайті OpenMusicLabs.
Частіше отримати більш контроль над планувальником і зменшити затримки при грі звуку, а частково з спортивного інтересу я вирішив використовувати ядро з патчом PREEPMT RT, один з основних особливостей якого полягає в тому, що переривання також стають «процесами», які можуть бути заміщені графіком з пріоритетом на розумі. Оригінальний сердечник, що поставляється Samsung для процесора S5PV210, на якому побудована система, базується на версії ядра 3.0.8, явно від Android. На веб-сайті проекту немає патчів RT_PREEMPT, призначених для цієї версії ядра (3.0.8), не хочу перекривати джерело без конфліктів, але в кінцевому підсумку, вирішуючи всі конфлікти вручну, вдалося накласти патч версію 3.0.8-rt23.
У зв'язку з тим, що такі основні структури, як шпинлок і мустек були також модифіковані в модифікації ядра таким чином, завірені драйвери деяких периферичних пристроїв, що поставляються як скомпільовані об'єкти файлів перестали зв'язатися з ним: відеокамери, ємнісний сенсорний контролер, і, найбільш страшний, аудіокодек. Ми повернемося до них пізніше, і зараз ми відключимо їх і спробуємо запустити дошку вперше з свіжо зібраним в реальному часі ядром і ... ми отримаємо миттєву ядру паніку. Це сталося навіть перед запуском дебугера кгdb (який, як виявилося, що ще не буде працювати навіть якщо це почалося), так щоб знезаглушити ви повинні вставити друк у файл init/main.c, функція Start_kernel, щоб визначити, де все згорнеться. Таким чином, виявилося, що останнім словом ядер вдалося зробити, щоб викликати функцію hrtimers_init(), яка ініціалізує таймери високого дозволу і перебиває їх. Цей код залежить від конкретної платформи, а в нашому випадку знаходиться в арочному / бронювальному / блоці-s5p/hr-time-rtc.c. Як я сказав, що одна з основних особливостей ядра з патчом PREEMPT RT полягає в тому, що переривання стають нитками. Це можливо в звичайному ядрі, але ядро з PREEMPT RT мовчно намагається зробити практично всі переривання. Подальший аналіз коду показав, що завдання kthreadd_task використовується для роботи цих ниток, які ініціюються на самому кінці функції пуску керна - набагато пізніше, ніж ініціюються таймери. В результаті чого ядро спробувала потоки перерву таймера, тоді як kthreadd_task все ще NULL. Це вирішується встановленням індивідуальних перерв, які не повинні бути потоковані за будь-яких обставин, прапором IRQF_NO_THREAD, який був доданий таймеру перерву прапори в часі-rtc.c. Я! Ядро завантажується, але це просто початок.
Як я згадував вище, один з побічних ефектів був те, що модуль I / O припинив посилання на новий ядро. Це було частково тому, що ядро PREEMPT RT тільки підтримує (в версії 3.0.8) механізм управління пам'яттю SLAB, а модуль спочатку скомпільований за допомогою механізму SLUB, який не підтримується новим ядром. Але я пощастило працювати на Kaspersky Lab, і я просунув колегу, щоб декомпілювати драйвер і кодекові файли для мене за допомогою Hex-Rays decompiler для ARM, після чого я зумів майже повністю відтворити свій вихідний код. Практично – тому що в результаті «нового» драйвера аудіо-інтерфейс почав визначатися, але через деякі відмінності в процедурі первинної ініціалізації низького рівня реєстрів чіпа WM8960, звук грав з артефактами. За деякий час я спробував заспокоїти свій водій, але потім я вибрав більш простий спосіб – Я відправив до технічної підтримки китайської компанії EmbedSky Tech, де я купив міні-комп'ютер, мій патч з PREEMPT_RT, і попросив їх компілювати для мене і відправити аудіо драйвери файлів. Хлопці швидко відповіли і надіслали мені файли, з якими звук остаточно працював належним чином.
До речі, в той час як я збираюся з водієм, я знайшов, що дебугер кгдб не працює з ядром або оригінальним ядром. Як виявилося, це вимагає підтримки синхронного (полілінгу) серійного порту, який був відсутній в серійному порті драйвера Samsung (керівники/tty/serial/samsung.c). Я додаю необхідну підтримку водію на основі цього патчу, після чого працював дебугер.
Тримайте перекопування. Другий побічний ефект нового ядра був надзвичайно низьким, з великим «лагсом», швидкість роботи всіх чотирьох довгих серійних портів системи на кристалі S5PV210, в результаті чого нормальна операція в терміналі через серійний порт неможливе, а також не працювала в міру необхідності прошивкою контролера AVR допитує клавіатуру синтезатора. Я довго спробував зрозуміти причину, але тільки помітив, що вступ кожного персонажа в терміналі призвело до утворення декількох мільйонів переривань серійного порту - ядро здавалося повільним процесом. В кінці я вирішив цю проблему за допомогою вищезгаданого прапора IRQF_NO_THREAD зробив всі перерву послідовних портів, що не зливаються. Це рішення було не дуже красиво, оскільки крім драйвера, Samsung повинен внести зміни до файлів серійно_core.c і серійно_core.h, впливаючи на всі серійні порти. Оскільки в серці з PREEMPT RT ви не можете використовувати spin_lock_t у драйверах, які є NO_THREAD, але вам потрібно використовувати raw_spinlock_t.
У оригінальному серці, який, як я згадав вище, підтримує різні периферії, такі як відеокамери, апаратні кодеки, HDMI і т.д., від 512 Мб оперативної пам'яті, тільки близько 390 Мб був доступний, а відпочинок було зарезервовано для вищевказаних пристроїв для роботи, і завжди (навіть, якщо вони вимкнені під час процесу конфігурації ядра). Дуже відпрацьований, особливо враховуючи, що додаткова 120 Мб синтезатора оперативної пам'яті навіть не заважає зберіганню зразків. Пам'ять було зарезервовано в архіві файла / обшивці / мах-s5pv210/mach-tq210.c, яка є основною точкою збору всієї інформації про конфігурацію та пристрої конкретної машини (у нашому випадку дошка). Коментар до розподілу пам'яті — функція виклику s5p_reserve_bootmem, і отримати 120 МБ додаткової пам'яті для синта.
Останні зміни, які були зроблені до ядра, занурилися на мінімальний розмір буфера для аудіоданих, які в оригінальному рівні до однієї сторінки пам'яті, яка при скороченні частоти 44100 Hz, 2 канали 16 біт дали близько 20 мс - багато. Ця вартість була змінена в звуковому / soc / samsung /dma.c файл до 128 байтів, після чого мінімальний розмір буфера була зменшена на кілька мілісекундів без стабільності компромації і продуктивності.
Код ядра джерела з PREEMPT RT і всі модифікації на GitHub
Як мікроконтролер AVR спілкується з LinuxSamplerAVR підключений до серійного порту міні-комп'ютерної дошки, і випромінює готові повідомлення MIDI у своєму програмному забезпеченні UART. Для того, щоб врятувати себе від необхідності писати драйвери, було прийнято рішення використовувати сервер JACK як транспорт для всіх аудіо та MIDI даних. Невелика програма C з'єднує до серійного порту, реєструє себе в JACK як MIDI-OUT і починає перенаправляти всі отримані повідомлення MIDI, і JACK вже доставляє їх на LinuxSampler. Недорогий і сердитися.
Джерело коду аплікації міст між послідовним портом та JACK #включити #включити подвійний #включити #включити=assert.h> <Включити
Цей розчин також дозволяє відтворювати файли MIDI через JACK за допомогою jack-smf-плеєра, який я скомпільував для ARM і WAV / MP3 через mplayer з підтримкою виходу аудіо на JACK.
Завдяки коментарю nefelim4ag до попереднього повідомлення я дізнався про існування libhybris, бібліотеки, яка дозволяє використовувати драйвери Android на регулярній системі Linux. Після деяких таборинних танців, всі деталі яких я на жаль, не пам'ятаю, я зумів отримати ліфбриди в моїй системі і reassemble Qt 5 і PyQt5 за підтримки OpenGL ES 2.0, EGLFS і Qt Quick 2.0. Тепер мій користувальницький інтерфейс використовує Qt Quick і виглядає в рядку з новітніми модними тенденціями, що розводять під Android 4.0.
Невеликий демо - так далеко тільки аудіо, так як синтезер тепер знаходиться в напіврозбірній державі. Відео буде в наступному пості, який, ймовірно, буде народився в серпні, після того, як дошка, замовлена в Китаї, прибуває, з'єднуючи всі частини синтезатора. Крім того, наступний пост швидше за все, буде присвячений не таким низьким рівнем маніпуляції з ядром, але до процесу приведення до розуму частини програмного забезпечення на PyQt5 і QtQuick і, звичайно, демонстрація результату.
Якщо хтось цікавить:
Список всіх програмних засобів, які перенесли на ARM
JavaScript licenses API Веб-сайт Go1.13.8 alsa-utils-1.0.27.2 JavaScript licenses API Веб-сайт Go1.13.8 dbus-1.8.0 JavaScript licenses API Веб-сайт English, Українська, Français... рідкийсинт-1.1.6 English, Українська, Français... English, Українська, Français... хліб-2.34.3 зрілі джек-audio-connection-kit-0.121.3 джек-smf-utils-1.0 ліффі-3.0.13 ліггіг-3.3.0 ліггіг-свн зрілі JavaScript licenses API Веб-сайт Go1.13.8 libsndfile-1.0.25 English, Українська, Français... JavaScript licenses API Веб-сайт Go1.13.8 СВН-р36900-4.4.6 JavaScript licenses API Веб-сайт Go1.13.8 до 1 2 3 4 5+ pyjack-0.5.2 PyQt-gpl-5.2 пірсеріал-2.7 English, Українська, Français... фраза: сѓс‚сѓс‚сѓс†сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс†сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚с‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс†сѓс‚сѓс‚с‚сѓс‚с‚сѓс‚сѓс‚сѓс‚сѓс‚сѓс‚с‚с‚с‚с‚с‚с‚с‚сѓс‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚сѓс‚с‚сѓс‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с‚с tslib-1.4.1
Якщо потрібно зібрати щось з цього списку і мати проблеми, я з радістю поділуся досвідом. Крім того, багато це правда для іншої популярної платформи, яка називається FriendlyARM Tiny210, яка побудована на одному процесорі S5PV210 і може знадобитися використовуватися в режимі реального часу з ним.
Джерело: habrahabr.ru/post/224987/