Меню

andipanda.dev

CaRadio: FastCarPlay, LIVI та відновлення роботи Carlinkit

У попередніх статтях я розповів, як вдалося запустити CarPlay на Raspberry Pi і яку роль у цій системі відіграє USB-донгл Carlinkit.

Але між першим успішним запуском FastCarPlay і появою працюючої CaRadio була ще одна історія, про яку я поки майже не згадував.

Вона пов'язана з вибором програмної основи, експериментами з іншим проектом і несподіваною проблемою, після якої CarPlay взагалі перестав підключатися.

Чому я обрав SDL3

У своїх перших експериментах з автомобільною магнітолою я використовував Qt і C++.

Qt — потужний інструмент, який дозволяє створювати повноцінні графічні застосунки. Але з часом я почав замислюватися, наскільки все це необхідно для пристрою, який має виконувати порівняно невеликий набір завдань.

Коли навесні 2026 року я знайшов FastCarPlay, однією з його переваг для мене стало те, що проект був написаний на C++ з використанням SDL.

Я почав знайомитися з SDL3 і зрозумів, що такий підхід мені подобається значно більше.

Для роботи графічного застосунку не обов'язково запускати X11 і використовувати цілий Qt Framework. Можна обійтися значно меншим набором компонентів і самостійно організувати інтерфейс.

Звісно, це не означає, що SDL3 в усьому кращий за Qt. Це інструменти для різних завдань.

Але для моєї магнітоли SDL3 виявився ближчим до того, що я хотів отримати: відносно невеликий застосунок без зайвих програмних прошарків.

До того ж FastCarPlay уже використовував SDL, тому перехід до власної реалізації на тій самій основі виглядав цілком логічним.

Перший запуск FastCarPlay

Після знайомства з вихідним кодом я зібрав FastCarPlay і спробував запустити його з моїм USB-донглом Carlinkit.

І CarPlay справді запрацював.

Щоправда, не все було ідеально.

Зараз я вже не згадаю всі проблеми, з якими зіткнувся під час перших запусків. Пам'ятаю лише, що система працювала не зовсім так, як очікувалося, і я почав шукати можливі причини.

Під час цих пошуків мені трапився ще один відкритий проект — LIVI.

Я вирішив спробувати і його.

Знайомство з LIVI

LIVI виявився досить великим проектом порівняно з FastCarPlay.

Крім того, він був написаний мовою програмування, з якою я не був знайомий.

Це не означає, що проект був поганим. Радше навпаки: після встановлення LIVI у мене працював коректно.

Але розбиратися у великій кодовій базі незнайомою мовою, а потім будувати на її основі власну магнітолу мені не хотілося.

Я віддаю перевагу C++, а для подібних саморобних пристроїв намагаюся дотримуватися одного принципу: що простіше, то надійніше.

Звісно, простота сама по собі нічого не гарантує.

Але з власного досвіду я помітив, що чим сильніше починаєш ускладнювати конструкцію на перших етапах, тим більше з'являється потенційних джерел проблем.

Додаткові залежності, служби, програмні прошарки — усе це доводиться налаштовувати, підтримувати й враховувати під час пошуку несправностей.

Тому мені хотілося залишити FastCarPlay за основу й поступово адаптувати його під свої завдання.

Однак після експерименту з LIVI виникла несподівана проблема.

Коли CarPlay перестав підключатися

Після запуску LIVI я повернувся до FastCarPlay.

І виявив, що тепер він взагалі перестав бачити телефон.

До цього CarPlay хоча б запускався, нехай і з деякими проблемами. Тепер підключення не відбувалося зовсім.

Точну причину я так і не встановив.

У мене виникло припущення, що під час роботи LIVI у донглі Carlinkit могло змінитися якесь налаштування або внутрішній стан, через що попередня процедура підключення перестала працювати.

Але це залишилося лише припущенням.

Факт був в іншому: один проект продовжував коректно працювати з адаптером, а другий більше не міг встановити з'єднання.

Саме ця відмінність і стала відправною точкою для подальшого пошуку.

Відновлення ініціалізації Carlinkit

Оскільки LIVI продовжував працювати, я вирішив використати його як орієнтир.

Завдання полягало не в тому, щоб переписати FastCarPlay іншою мовою або перенести до нього весь код LIVI.

Мені потрібно було розібратися, чим відрізняється процедура ініціалізації USB-донгла в цих двох проектах.

Я почав вивчати відповідні частини реалізації та порівнювати послідовність взаємодії з Carlinkit.

Поступово вдалося виявити відмінності, які могли впливати на встановлення з'єднання.

На основі цих спостережень я вніс зміни до процедури ініціалізації FastCarPlay.

Після виправлень телефон знову почав підключатися.

Але цього разу результат виявився кращим, ніж під час перших експериментів: вдалося досягти стабільного підключення та роботи CarPlay.

Для мене це був важливий етап.

До цього я переважно намагався запустити й адаптувати вже наявні рішення. Тепер довелося розбиратися безпосередньо у взаємодії застосунку з USB-донглом і шукати причину несумісності.

При цьому я не займався розробкою протоколу CarPlay з нуля.

Я використовував наявні відкриті реалізації, порівнював їхню поведінку й виправляв ту частину взаємодії з адаптером, яка заважала нормальній роботі моєї системи.

Чому я все-таки залишився з FastCarPlay

Після цих експериментів у мене були дві робочі відправні точки.

LIVI показав, що адаптер здатний коректно підключатися й працювати. Ба більше, його реалізація допомогла розібратися з проблемою ініціалізації.

Але за основу для подальшої розробки я все одно обрав FastCarPlay.

Причин було кілька.

Насамперед — C++. Це мова, з якою я давно працюю і якою мені зручно розробляти та підтримувати власні проекти.

Друга причина — SDL3. Мені сподобалася можливість створити графічний застосунок без необхідності використовувати X11 і Qt.

І третя — розмір та складність проекту.

Я не хотів перетворювати саморобну магнітолу на велику програмну систему ще до того, як запрацюють її основні функції.

Мій підхід досить простий: спочатку досягти надійної роботи мінімально необхідного набору компонентів, а вже потім поступово додавати нові можливості.

Звісно, у міру розвитку CaRadio застосунок неминуче ставав складнішим.

Але мені хотілося, щоб це ускладнення було наслідком конкретних завдань, а не з'являлося заздалегідь.

Від експериментів до власної CaRadio

Коли проблему підключення вдалося вирішити, у мене нарешті з'явилася робоча програмна основа, на яку можна було спиратися.

FastCarPlay забезпечував взаємодію з Carlinkit, SDL3 підходив для створення власного інтерфейсу, а C++ дозволяв розвивати застосунок у звичному для мене середовищі.

Це ще не була готова автомобільна магнітола.

Потрібно було об'єднати CarPlay з іншими функціями CaRadio, продумати керування застосунком і адаптувати його до повсякденного використання в автомобілі.

Але одне з найнеприємніших питань уже було вирішено: підключення телефона перестало бути непередбачуваним експериментом.

Саме після цього я зміг зосередитися на подальшому розвитку власної магнітоли, а не на постійних спробах змусити CarPlay хоча б запуститися.

Що далі

Ця історія вкотре нагадала мені, чому я волію не ускладнювати власні проекти без необхідності.

Іноді невелика програма, яку добре розумієш, виявляється зручнішою за велике готове рішення з безліччю можливостей.

Водночас без LIVI мені, можливо, знадобилося б значно більше часу, щоб розібратися з проблемою підключення Carlinkit.

Тому обидва проекти відіграли свою роль у розвитку CaRadio.

FastCarPlay став програмною основою, а LIVI допоміг знайти й усунути проблему, яка заважала рухатися далі.

У наступних статтях я розповім про інші частини CaRadio і про те, які завдання довелося вирішувати, щоб перетворити працюючий CarPlay на повноцінну автомобільну магнітолу.